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 <svl/itemiter.hxx>
21 : #include <svtools/imap.hxx>
22 : #include <tools/helpers.hxx>
23 : #include <editeng/protitem.hxx>
24 : #include <editeng/opaqitem.hxx>
25 : #include <editeng/ulspitem.hxx>
26 : #include <editeng/frmdiritem.hxx>
27 : #include <fmtfsize.hxx>
28 : #include <fmtclds.hxx>
29 : #include <fmtcntnt.hxx>
30 : #include <fmturl.hxx>
31 : #include <fmtsrnd.hxx>
32 : #include <fmtornt.hxx>
33 : #include <fmtcnct.hxx>
34 : #include <layhelp.hxx>
35 : #include <ndgrf.hxx>
36 : #include <tolayoutanchoredobjectposition.hxx>
37 : #include <fmtfollowtextflow.hxx>
38 : #include <sortedobjs.hxx>
39 : #include <objectformatter.hxx>
40 : #include <ndole.hxx>
41 : #include <swtable.hxx>
42 : #include <svx/svdpage.hxx>
43 : #include "layouter.hxx"
44 : #include "pagefrm.hxx"
45 : #include "rootfrm.hxx"
46 : #include "viewimp.hxx"
47 : #include "viewopt.hxx"
48 : #include "dcontact.hxx"
49 : #include "dflyobj.hxx"
50 : #include "dview.hxx"
51 : #include "frmtool.hxx"
52 : #include "hints.hxx"
53 : #include "tabfrm.hxx"
54 : #include "txtfrm.hxx"
55 : #include "notxtfrm.hxx"
56 : #include "flyfrms.hxx"
57 : #include "sectfrm.hxx"
58 : #include <vcl/svapp.hxx>
59 : #include "switerator.hxx"
60 :
61 : using namespace ::com::sun::star;
62 :
63 484762 : TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
64 :
65 1310 : SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
66 : SwLayoutFrm( pFmt, pSib ),
67 : SwAnchoredObject(), // #i26791#
68 : pPrevLink( 0 ),
69 : pNextLink( 0 ),
70 : bInCnt( sal_False ),
71 : bAtCnt( sal_False ),
72 : bLayout( sal_False ),
73 : bAutoPosition( sal_False ),
74 : bNoShrink( sal_False ),
75 : bLockDeleteContent( sal_False ),
76 1310 : m_bValidContentPos( false )
77 : {
78 1310 : mnType = FRMC_FLY;
79 :
80 1310 : bInvalid = bNotifyBack = sal_True;
81 : bLocked = bMinHeight =
82 1310 : bHeightClipped = bWidthClipped = bFormatHeightOnly = sal_False;
83 :
84 : // Size setting: Fixed size is always the width
85 1310 : const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
86 : sal_uInt16 nDir =
87 1310 : ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue();
88 1310 : if( FRMDIR_ENVIRONMENT == nDir )
89 : {
90 1273 : mbDerivedVert = 1;
91 1273 : mbDerivedR2L = 1;
92 : }
93 : else
94 : {
95 37 : mbInvalidVert = 0;
96 37 : mbDerivedVert = 0;
97 37 : mbDerivedR2L = 0;
98 37 : if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir )
99 : {
100 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
101 37 : mbVertLR = 0;
102 37 : mbVertical = 0;
103 : }
104 : else
105 : {
106 0 : const SwViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
107 0 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
108 : {
109 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
110 0 : mbVertLR = 0;
111 0 : mbVertical = 0;
112 : }
113 : else
114 : {
115 0 : mbVertical = 1;
116 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
117 0 : if ( FRMDIR_VERT_TOP_LEFT == nDir )
118 0 : mbVertLR = 1;
119 : else
120 0 : mbVertLR = 0;
121 : }
122 : }
123 :
124 37 : mbInvalidR2L = 0;
125 37 : if( FRMDIR_HORI_RIGHT_TOP == nDir )
126 0 : mbRightToLeft = 1;
127 : else
128 37 : mbRightToLeft = 0;
129 : }
130 :
131 1310 : Frm().Width( rFrmSize.GetWidth() );
132 1310 : Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
133 :
134 : // Fixed or variable Height?
135 1310 : if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
136 37 : bMinHeight = sal_True;
137 1273 : else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
138 473 : mbFixSize = sal_True;
139 :
140 : // insert columns, if necessary
141 1310 : InsertColumns();
142 :
143 : // First the Init, then the Content:
144 : // This is due to the fact that the Content may have Objects/Frames,
145 : // which are then registered
146 1310 : InitDrawObj( sal_False );
147 :
148 1310 : Chain( pAnch );
149 :
150 1310 : InsertCnt();
151 :
152 : // Put it somewhere outside so that out document is not formatted unnecessarily often
153 1310 : Frm().Pos().setX(FAR_AWAY);
154 1310 : Frm().Pos().setY(FAR_AWAY);
155 1310 : }
156 :
157 1310 : void SwFlyFrm::Chain( SwFrm* _pAnch )
158 : {
159 : // Connect to chain neighboors.
160 : // No problem, if a neighboor doesn't exist - the construction of the
161 : // neighboor will make the connection
162 1310 : const SwFmtChain& rChain = GetFmt()->GetChain();
163 1310 : if ( rChain.GetPrev() || rChain.GetNext() )
164 : {
165 2 : if ( rChain.GetNext() )
166 : {
167 1 : SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
168 1 : if ( pFollow )
169 : {
170 : OSL_ENSURE( !pFollow->GetPrevLink(), "wrong chain detected" );
171 0 : if ( !pFollow->GetPrevLink() )
172 0 : SwFlyFrm::ChainFrames( this, pFollow );
173 : }
174 : }
175 2 : if ( rChain.GetPrev() )
176 : {
177 1 : SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
178 1 : if ( pMaster )
179 : {
180 : OSL_ENSURE( !pMaster->GetNextLink(), "wrong chain detected" );
181 1 : if ( !pMaster->GetNextLink() )
182 1 : SwFlyFrm::ChainFrames( pMaster, this );
183 : }
184 : }
185 : }
186 1310 : }
187 :
188 1310 : void SwFlyFrm::InsertCnt()
189 : {
190 1310 : if ( !GetPrevLink() )
191 : {
192 1309 : const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
193 : OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( no content prepared." );
194 1309 : sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
195 : // Lower() means SwColumnFrm; the Content then needs to be instered into the (Column)BodyFrm
196 1309 : ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
197 2618 : GetFmt()->GetDoc(), nIndex );
198 :
199 : // NoTxt always have a fixed height.
200 1309 : if ( Lower() && Lower()->IsNoTxtFrm() )
201 : {
202 712 : mbFixSize = sal_True;
203 712 : bMinHeight = sal_False;
204 : }
205 : }
206 1310 : }
207 :
208 1310 : void SwFlyFrm::InsertColumns()
209 : {
210 : // #i97379#
211 : // Check, if column are allowed.
212 : // Columns are not allowed for fly frames, which represent graphics or embedded objects.
213 1310 : const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
214 : OSL_ENSURE( rCntnt.GetCntntIdx(), "<SwFlyFrm::InsertColumns()> - no content prepared." );
215 1310 : SwNodeIndex aFirstCntnt( *(rCntnt.GetCntntIdx()), 1 );
216 1310 : if ( aFirstCntnt.GetNode().IsNoTxtNode() )
217 : {
218 2022 : return;
219 : }
220 :
221 598 : const SwFmtCol &rCol = GetFmt()->GetCol();
222 598 : if ( rCol.GetNumCols() > 1 )
223 : {
224 : // Start off PrtArea to be as large as Frm, so that we can put in the columns
225 : // properly. It'll adjust later on.
226 0 : Prt().Width( Frm().Width() );
227 0 : Prt().Height( Frm().Height() );
228 0 : const SwFmtCol aOld; // ChgColumns() also needs an old value passed
229 0 : ChgColumns( aOld, rCol );
230 598 : }
231 : }
232 :
233 2620 : SwFlyFrm::~SwFlyFrm()
234 : {
235 : // Accessible objects for fly frames will be destroyed in this destructor.
236 : // For frames bound as char or frames that don't have an anchor we have
237 : // to do that ourselves. For any other frame the call RemoveFly at the
238 : // anchor will do that.
239 1310 : if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
240 : {
241 557 : SwRootFrm *pRootFrm = getRootFrm();
242 557 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
243 : {
244 0 : SwViewShell *pVSh = pRootFrm->GetCurrShell();
245 0 : if( pVSh && pVSh->Imp() )
246 : {
247 : // Lowers aren't disposed already, so we have to do a recursive
248 : // dispose
249 0 : pVSh->Imp()->DisposeAccessibleFrm( this, true );
250 : }
251 : }
252 : }
253 :
254 1310 : if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
255 : {
256 : // OD 2004-01-19 #110582#
257 1310 : Unchain();
258 :
259 : // OD 2004-01-19 #110582#
260 1310 : DeleteCnt();
261 :
262 1310 : if ( GetAnchorFrm() )
263 1310 : AnchorFrm()->RemoveFly( this );
264 : }
265 :
266 1310 : FinitDrawObj();
267 1310 : }
268 :
269 0 : const IDocumentDrawModelAccess* SwFlyFrm::getIDocumentDrawModelAccess()
270 : {
271 0 : return GetFmt()->getIDocumentDrawModelAccess();
272 : }
273 :
274 : // OD 2004-01-19 #110582#
275 1310 : void SwFlyFrm::Unchain()
276 : {
277 1310 : if ( GetPrevLink() )
278 0 : UnchainFrames( GetPrevLink(), this );
279 1310 : if ( GetNextLink() )
280 1 : UnchainFrames( this, GetNextLink() );
281 1310 : }
282 :
283 : // OD 2004-01-19 #110582#
284 1310 : void SwFlyFrm::DeleteCnt()
285 : {
286 : // #110582#-2
287 1310 : if ( IsLockDeleteContent() )
288 1310 : return;
289 :
290 1310 : SwFrm* pFrm = pLower;
291 4213 : while ( pFrm )
292 : {
293 3207 : while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
294 : {
295 21 : SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
296 21 : if ( pAnchoredObj->ISA(SwFlyFrm) )
297 18 : delete pAnchoredObj;
298 3 : else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
299 : {
300 : // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
301 3 : SdrObject* pObj = pAnchoredObj->DrawObj();
302 3 : if ( pObj->ISA(SwDrawVirtObj) )
303 : {
304 0 : SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
305 0 : pDrawVirtObj->RemoveFromWriterLayout();
306 0 : pDrawVirtObj->RemoveFromDrawingPage();
307 : }
308 : else
309 : {
310 : SwDrawContact* pContact =
311 3 : static_cast<SwDrawContact*>(::GetUserCall( pObj ));
312 3 : if ( pContact )
313 : {
314 3 : pContact->DisconnectFromLayout();
315 : }
316 : }
317 : }
318 : }
319 :
320 1593 : pFrm->Remove();
321 1593 : delete pFrm;
322 1593 : pFrm = pLower;
323 : }
324 :
325 1310 : InvalidatePage();
326 : }
327 :
328 744 : sal_uInt32 SwFlyFrm::_GetOrdNumForNewRef( const SwFlyDrawContact* pContact )
329 : {
330 744 : sal_uInt32 nOrdNum( 0L );
331 :
332 : // search for another Writer fly frame registered at same frame format
333 744 : SwIterator<SwFlyFrm,SwFmt> aIter( *pContact->GetFmt() );
334 744 : const SwFlyFrm* pFlyFrm( 0L );
335 1488 : for ( pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
336 : {
337 852 : if ( pFlyFrm != this )
338 : {
339 108 : break;
340 : }
341 : }
342 :
343 744 : if ( pFlyFrm )
344 : {
345 : // another Writer fly frame found. Take its order number
346 108 : nOrdNum = pFlyFrm->GetVirtDrawObj()->GetOrdNum();
347 : }
348 : else
349 : {
350 : // no other Writer fly frame found. Take order number of 'master' object
351 : // #i35748# - use method <GetOrdNumDirect()> instead
352 : // of method <GetOrdNum()> to avoid a recalculation of the order number,
353 : // which isn't intended.
354 636 : nOrdNum = pContact->GetMaster()->GetOrdNumDirect();
355 : }
356 :
357 744 : return nOrdNum;
358 : }
359 :
360 1310 : SwVirtFlyDrawObj* SwFlyFrm::CreateNewRef( SwFlyDrawContact *pContact )
361 : {
362 1310 : SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *pContact->GetMaster(), this );
363 1310 : pDrawObj->SetModel( pContact->GetMaster()->GetModel() );
364 1310 : pDrawObj->SetUserCall( pContact );
365 :
366 : // The Reader creates the Masters and inserts them into the Page in
367 : // order to transport the z-order.
368 : // After creating the first Reference the Masters are removed from the
369 : // List and are not important anymore.
370 1310 : SdrPage* pPg( 0L );
371 1310 : if ( 0 != ( pPg = pContact->GetMaster()->GetPage() ) )
372 : {
373 566 : const sal_uInt32 nOrdNum = pContact->GetMaster()->GetOrdNum();
374 566 : pPg->ReplaceObject( pDrawObj, nOrdNum );
375 : }
376 : // #i27030# - insert new <SwVirtFlyDrawObj> instance
377 : // into drawing page with correct order number
378 : else
379 : {
380 744 : pContact->GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
381 744 : InsertObject( pDrawObj, _GetOrdNumForNewRef( pContact ) );
382 : }
383 : // #i38889# - assure, that new <SwVirtFlyDrawObj> instance
384 : // is in a visible layer.
385 1310 : pContact->MoveObjToVisibleLayer( pDrawObj );
386 1310 : return pDrawObj;
387 : }
388 :
389 1310 : void SwFlyFrm::InitDrawObj( sal_Bool bNotify )
390 : {
391 : // Find ContactObject from the Format. If there's already one, we just
392 : // need to create a new Ref, else we create the Contact now.
393 :
394 1310 : IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
395 1310 : SwFlyDrawContact *pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
396 1310 : if ( !pContact )
397 : {
398 : // #i52858# - method name changed
399 480 : pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
400 480 : pIDDMA->GetOrCreateDrawModel() );
401 : }
402 : OSL_ENSURE( pContact, "InitDrawObj failed" );
403 : // OD 2004-03-22 #i26791#
404 1310 : SetDrawObj( *(CreateNewRef( pContact )) );
405 :
406 : // Set the right Layer
407 : // OD 2004-01-19 #110582#
408 1310 : SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
409 1310 : SdrLayerID nHellId = pIDDMA->GetHellId();
410 : // OD 2004-03-22 #i26791#
411 2620 : GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
412 : ? nHeavenId
413 2620 : : nHellId );
414 1310 : if ( bNotify )
415 0 : NotifyDrawObj();
416 1310 : }
417 :
418 1310 : void SwFlyFrm::FinitDrawObj()
419 : {
420 1310 : if ( !GetVirtDrawObj() )
421 1310 : return;
422 :
423 : // Deregister from SdrPageViews if the Objects is still selected there.
424 1310 : if ( !GetFmt()->GetDoc()->IsInDtor() )
425 : {
426 1310 : SwViewShell *p1St = getRootFrm()->GetCurrShell();
427 1310 : if ( p1St )
428 : {
429 65 : SwViewShell *pSh = p1St;
430 65 : do
431 : { // At the moment the Drawing can do just do an Unmark on everything,
432 : // as the Object was already removed
433 65 : if( pSh->HasDrawView() )
434 65 : pSh->Imp()->GetDrawView()->UnmarkAll();
435 65 : pSh = (SwViewShell*)pSh->GetNext();
436 :
437 : } while ( pSh != p1St );
438 : }
439 : }
440 :
441 : // Take VirtObject to the grave.
442 : // If the last VirtObject is destroyed, the DrawObject and the DrawContact
443 : // also need to be destroyed.
444 1310 : SwFlyDrawContact *pMyContact = 0;
445 1310 : if ( GetFmt() )
446 : {
447 1310 : bool bContinue = true;
448 1310 : SwIterator<SwFrm,SwFmt> aFrmIter( *GetFmt() );
449 2548 : for ( SwFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
450 1346 : if ( pFrm != this )
451 : {
452 : // don't delete Contact if there is still a Frm
453 108 : bContinue = false;
454 108 : break;
455 : }
456 :
457 1310 : if ( bContinue )
458 : // no Frm left, find Contact object to destroy
459 1202 : pMyContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
460 : }
461 :
462 : // OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master'
463 : // <SdrObject> to assure, that a <SwXFrame::dispose()> doesn't delete the
464 : // Writer fly frame again.
465 1310 : if ( pMyContact )
466 : {
467 1202 : pMyContact->GetMaster()->SetUserCall( 0 );
468 : }
469 1310 : GetVirtDrawObj()->SetUserCall( 0 ); // Else calls delete of the ContactObj
470 1310 : delete GetVirtDrawObj(); // Deregisters itself at the Master
471 1310 : delete pMyContact; // Destroys the Master itself
472 : }
473 :
474 1 : void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
475 : {
476 : OSL_ENSURE( pMaster && pFollow, "uncomplete chain" );
477 : OSL_ENSURE( !pMaster->GetNextLink(), "link can not be changed" );
478 : OSL_ENSURE( !pFollow->GetPrevLink(), "link can not be changed" );
479 :
480 1 : pMaster->pNextLink = pFollow;
481 1 : pFollow->pPrevLink = pMaster;
482 :
483 1 : if ( pMaster->ContainsCntnt() )
484 : {
485 : // To get a text flow we need to invalidate
486 1 : SwFrm *pInva = pMaster->FindLastLower();
487 1 : SWRECTFN( pMaster )
488 1 : const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
489 3 : while ( pInva )
490 : {
491 1 : if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 )
492 : {
493 0 : pInva->InvalidateSize();
494 0 : pInva->Prepare( PREP_CLEAR );
495 0 : pInva = pInva->FindPrev();
496 : }
497 : else
498 1 : pInva = 0;
499 : }
500 : }
501 :
502 1 : if ( pFollow->ContainsCntnt() )
503 : {
504 : // There's only the content from the Masters left; the content from the Follow
505 : // does not have any Frames left (should always be exactly one empty TxtNode).
506 0 : SwFrm *pFrm = pFollow->ContainsCntnt();
507 : OSL_ENSURE( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
508 0 : pFrm->Cut();
509 0 : delete pFrm;
510 : }
511 :
512 : // invalidate accessible relation set (accessibility wrapper)
513 1 : SwViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
514 1 : if( pSh )
515 : {
516 1 : SwRootFrm* pLayout = pMaster->getRootFrm();
517 1 : if( pLayout && pLayout->IsAnyShellAccessible() )
518 0 : pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
519 : }
520 1 : }
521 :
522 1 : void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
523 : {
524 1 : pMaster->pNextLink = 0;
525 1 : pFollow->pPrevLink = 0;
526 :
527 1 : if ( pFollow->ContainsCntnt() )
528 : {
529 : // The Master sucks up the content of the Follow
530 0 : SwLayoutFrm *pUpper = pMaster;
531 0 : if ( pUpper->Lower()->IsColumnFrm() )
532 : {
533 0 : pUpper = static_cast<SwLayoutFrm*>(pUpper->GetLastLower());
534 0 : pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower()); // The (Column)BodyFrm
535 : OSL_ENSURE( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
536 : }
537 0 : SwFlyFrm *pFoll = pFollow;
538 0 : while ( pFoll )
539 : {
540 0 : SwFrm *pTmp = ::SaveCntnt( pFoll );
541 0 : if ( pTmp )
542 0 : ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true );
543 0 : pFoll->SetCompletePaint();
544 0 : pFoll->InvalidateSize();
545 0 : pFoll = pFoll->GetNextLink();
546 : }
547 : }
548 :
549 : // The Follow needs his own content to be served
550 1 : const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
551 : OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( No content prepared." );
552 1 : sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
553 : // Lower() means SwColumnFrm: this one contains another SwBodyFrm
554 1 : ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
555 : : (SwLayoutFrm*)pFollow,
556 2 : pFollow->GetFmt()->GetDoc(), ++nIndex );
557 :
558 : // invalidate accessible relation set (accessibility wrapper)
559 1 : SwViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
560 1 : if( pSh )
561 : {
562 0 : SwRootFrm* pLayout = pMaster->getRootFrm();
563 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
564 0 : pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
565 : }
566 1 : }
567 :
568 2 : SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
569 : {
570 : // We look for the Fly that's in the same Area.
571 : // Areas can for now only be Head/Footer or Flys.
572 :
573 2 : if ( !pAnch ) // If an Anchor was passed along, that one counts (ctor!)
574 0 : pAnch = AnchorFrm();
575 :
576 : SwLayoutFrm *pLay;
577 2 : if ( pAnch->IsInFly() )
578 0 : pLay = pAnch->FindFlyFrm();
579 : else
580 : {
581 : // FindFooterOrHeader is not appropriate here, as we may not have a
582 : // connection to the Anchor yet.
583 2 : pLay = pAnch->GetUpper();
584 10 : while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
585 6 : pLay = pLay->GetUpper();
586 : }
587 :
588 2 : SwIterator<SwFlyFrm,SwFmt> aIter( rChain );
589 2 : SwFlyFrm *pFly = aIter.First();
590 2 : if ( pLay )
591 : {
592 0 : while ( pFly )
593 : {
594 0 : if ( pFly->GetAnchorFrm() )
595 : {
596 0 : if ( pFly->GetAnchorFrm()->IsInFly() )
597 : {
598 0 : if ( pFly->AnchorFrm()->FindFlyFrm() == pLay )
599 0 : break;
600 : }
601 0 : else if ( pLay == pFly->FindFooterOrHeader() )
602 0 : break;
603 : }
604 0 : pFly = aIter.Next();
605 : }
606 : }
607 : else if ( pFly )
608 : {
609 : OSL_ENSURE( !aIter.Next(), "chain with more than one instance" );
610 : }
611 2 : return pFly;
612 : }
613 :
614 1 : SwFrm *SwFlyFrm::FindLastLower()
615 : {
616 1 : SwFrm *pRet = ContainsAny();
617 1 : if ( pRet && pRet->IsInTab() )
618 0 : pRet = pRet->FindTabFrm();
619 1 : SwFrm *pNxt = pRet;
620 3 : while ( pNxt && IsAnLower( pNxt ) )
621 1 : { pRet = pNxt;
622 1 : pNxt = pNxt->FindNext();
623 : }
624 1 : return pRet;
625 : }
626 :
627 78 : sal_Bool SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
628 : {
629 78 : sal_Bool bRet = sal_False;
630 78 : SwTwips nDiffHeight = Frm().Height();
631 78 : if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
632 16 : mbFixSize = bMinHeight = sal_False;
633 : else
634 : {
635 62 : if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
636 : {
637 61 : mbFixSize = sal_True;
638 61 : bMinHeight = sal_False;
639 : }
640 1 : else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
641 : {
642 1 : mbFixSize = sal_False;
643 1 : bMinHeight = sal_True;
644 : }
645 62 : nDiffHeight -= rFrmSize.GetHeight();
646 : }
647 : // If the Fly contains columns, we already need to set the Fly
648 : // and the Columns to the required value or else we run into problems.
649 78 : if ( Lower() )
650 : {
651 78 : if ( Lower()->IsColumnFrm() )
652 : {
653 0 : const SwRect aOld( GetObjRectWithSpaces() );
654 0 : const Size aOldSz( Prt().SSize() );
655 0 : const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
656 0 : maFrm.Height( maFrm.Height() - nDiffHeight );
657 0 : maFrm.Width ( maFrm.Width() - nDiffWidth );
658 : // #i68520#
659 0 : InvalidateObjRectWithSpaces();
660 0 : maPrt.Height( maPrt.Height() - nDiffHeight );
661 0 : maPrt.Width ( maPrt.Width() - nDiffWidth );
662 0 : ChgLowersProp( aOldSz );
663 0 : ::Notify( this, FindPageFrm(), aOld );
664 0 : mbValidPos = sal_False;
665 0 : bRet = sal_True;
666 : }
667 78 : else if ( Lower()->IsNoTxtFrm() )
668 : {
669 71 : mbFixSize = sal_True;
670 71 : bMinHeight = sal_False;
671 : }
672 : }
673 78 : return bRet;
674 : }
675 :
676 259 : void SwFlyFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
677 : {
678 259 : sal_uInt8 nInvFlags = 0;
679 :
680 259 : if (pNew && pOld && RES_ATTRSET_CHG == pNew->Which())
681 : {
682 133 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
683 266 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
684 266 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
685 266 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
686 : while( true )
687 : {
688 : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
689 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
690 133 : &aOldSet, &aNewSet );
691 133 : if( aNIter.IsAtEnd() )
692 133 : break;
693 0 : aNIter.NextItem();
694 0 : aOIter.NextItem();
695 : }
696 133 : if ( aOldSet.Count() || aNewSet.Count() )
697 135 : SwLayoutFrm::Modify( &aOldSet, &aNewSet );
698 : }
699 : else
700 126 : _UpdateAttr( pOld, pNew, nInvFlags );
701 :
702 259 : if ( nInvFlags != 0 )
703 : {
704 147 : _Invalidate();
705 147 : if ( nInvFlags & 0x01 )
706 : {
707 147 : _InvalidatePos();
708 : // #i68520#
709 147 : InvalidateObjRectWithSpaces();
710 : }
711 147 : if ( nInvFlags & 0x02 )
712 : {
713 78 : _InvalidateSize();
714 : // #i68520#
715 78 : InvalidateObjRectWithSpaces();
716 : }
717 147 : if ( nInvFlags & 0x04 )
718 78 : _InvalidatePrt();
719 147 : if ( nInvFlags & 0x08 )
720 144 : SetNotifyBack();
721 147 : if ( nInvFlags & 0x10 )
722 78 : SetCompletePaint();
723 147 : if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
724 74 : ClrContourCache( GetVirtDrawObj() );
725 : SwRootFrm *pRoot;
726 147 : if ( nInvFlags & 0x20 && 0 != (pRoot = getRootFrm()) )
727 78 : pRoot->InvalidateBrowseWidth();
728 : // #i28701#
729 147 : if ( nInvFlags & 0x80 )
730 : {
731 : // update sorted object lists, the Writer fly frame is registered at.
732 81 : UpdateObjInSortedList();
733 : }
734 :
735 : // #i87645# - reset flags for the layout process (only if something has been invalidated)
736 147 : ResetLayoutProcessBools();
737 : }
738 259 : }
739 :
740 259 : void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
741 : sal_uInt8 &rInvFlags,
742 : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
743 : {
744 259 : bool bClear = true;
745 259 : const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
746 259 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
747 259 : switch( nWhich )
748 : {
749 : case RES_VERT_ORIENT:
750 : case RES_HORI_ORIENT:
751 : // OD 22.09.2003 #i18732# - consider new option 'follow text flow'
752 : case RES_FOLLOW_TEXT_FLOW:
753 : {
754 : // ATTENTION: Always also change Action in ChgRePos()!
755 66 : rInvFlags |= 0x09;
756 : }
757 66 : break;
758 : // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
759 : case RES_WRAP_INFLUENCE_ON_OBJPOS:
760 : {
761 0 : rInvFlags |= 0x89;
762 : }
763 0 : break;
764 : case RES_SURROUND:
765 : {
766 : // OD 2004-05-13 #i28701# - invalidate position on change of
767 : // wrapping style.
768 : //rInvFlags |= 0x40;
769 3 : rInvFlags |= 0x41;
770 : // The background needs to messaged and invalidated
771 3 : const SwRect aTmp( GetObjRectWithSpaces() );
772 3 : NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
773 :
774 : // By changing the flow of frame-bound Frames, a vertical alignment
775 : // can be activated/deactivated => MakeFlyPos
776 3 : if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
777 0 : rInvFlags |= 0x09;
778 :
779 : // Delete contour in the Node if necessary
780 6 : if ( Lower() && Lower()->IsNoTxtFrm() &&
781 3 : !GetFmt()->GetSurround().IsContour() )
782 : {
783 1 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
784 1 : if ( pNd->HasContour() )
785 0 : pNd->SetContour( 0 );
786 : }
787 : // #i28701# - perform reorder of object lists
788 : // at anchor frame and at page frame.
789 3 : rInvFlags |= 0x80;
790 : }
791 3 : break;
792 :
793 : case RES_PROTECT:
794 1 : if (pNew)
795 : {
796 1 : const SvxProtectItem *pP = (SvxProtectItem*)pNew;
797 1 : GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() );
798 1 : GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
799 1 : if( pSh )
800 : {
801 1 : SwRootFrm* pLayout = getRootFrm();
802 1 : if( pLayout && pLayout->IsAnyShellAccessible() )
803 0 : pSh->Imp()->InvalidateAccessibleEditableState( true, this );
804 : }
805 : }
806 1 : break;
807 : case RES_COL:
808 0 : if (pOld && pNew)
809 : {
810 0 : ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
811 0 : const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
812 0 : if ( FrmSizeChg( rNew ) )
813 0 : NotifyDrawObj();
814 0 : rInvFlags |= 0x1A;
815 0 : break;
816 : }
817 :
818 : case RES_FRM_SIZE:
819 : case RES_FMT_CHG:
820 : {
821 78 : const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
822 78 : if ( FrmSizeChg( rNew ) )
823 0 : NotifyDrawObj();
824 78 : rInvFlags |= 0x7F;
825 78 : if ( RES_FMT_CHG == nWhich )
826 : {
827 19 : SwRect aNew( GetObjRectWithSpaces() );
828 19 : SwRect aOld( maFrm );
829 19 : const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
830 19 : aOld.Top( std::max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
831 19 : aOld.SSize().Height()+= rUL.GetLower();
832 19 : const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
833 19 : aOld.Left ( std::max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
834 19 : aOld.SSize().Width() += rLR.GetRight();
835 19 : aNew.Union( aOld );
836 19 : NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
837 :
838 : // Special case:
839 : // When assigning a template we cannot rely on the old column
840 : // attribute. As there need to be at least enough for ChgColumns,
841 : // we need to create a temporary attribute.
842 19 : SwFmtCol aCol;
843 19 : if ( Lower() && Lower()->IsColumnFrm() )
844 : {
845 0 : sal_uInt16 nCol = 0;
846 0 : SwFrm *pTmp = Lower();
847 0 : do
848 0 : { ++nCol;
849 0 : pTmp = pTmp->GetNext();
850 : } while ( pTmp );
851 0 : aCol.Init( nCol, 0, 1000 );
852 : }
853 19 : ChgColumns( aCol, GetFmt()->GetCol() );
854 : }
855 :
856 78 : SwFmtURL aURL( GetFmt()->GetURL() );
857 78 : if ( aURL.GetMap() )
858 : {
859 : const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
860 : *(SwFmtFrmSize*)pNew :
861 1 : ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
862 : //#35091# Can be "times zero", when loading the template
863 1 : if ( rOld.GetWidth() && rOld.GetHeight() )
864 : {
865 :
866 1 : Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
867 1 : Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
868 1 : aURL.GetMap()->Scale( aScaleX, aScaleY );
869 1 : SwFrmFmt *pFmt = GetFmt();
870 1 : pFmt->LockModify();
871 1 : pFmt->SetFmtAttr( aURL );
872 1 : pFmt->UnlockModify();
873 : }
874 : }
875 78 : const SvxProtectItem &rP = GetFmt()->GetProtect();
876 78 : GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() );
877 78 : GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
878 :
879 78 : if ( pSh )
880 78 : pSh->InvalidateWindows( Frm() );
881 78 : const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
882 78 : const sal_uInt8 nId = GetFmt()->GetOpaque().GetValue() ?
883 46 : pIDDMA->GetHeavenId() :
884 124 : pIDDMA->GetHellId();
885 78 : GetVirtDrawObj()->SetLayer( nId );
886 :
887 78 : if ( Lower() )
888 : {
889 : // Delete contour in the Node if necessary
890 149 : if( Lower()->IsNoTxtFrm() &&
891 71 : !GetFmt()->GetSurround().IsContour() )
892 : {
893 70 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
894 70 : if ( pNd->HasContour() )
895 0 : pNd->SetContour( 0 );
896 : }
897 8 : else if( !Lower()->IsColumnFrm() )
898 : {
899 8 : SwFrm* pFrm = GetLastLower();
900 8 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
901 1 : pFrm->Prepare( PREP_ADJUST_FRM );
902 : }
903 : }
904 :
905 : // #i28701# - perform reorder of object lists
906 : // at anchor frame and at page frame.
907 78 : rInvFlags |= 0x80;
908 :
909 78 : break;
910 : }
911 : case RES_UL_SPACE:
912 : case RES_LR_SPACE:
913 : {
914 0 : rInvFlags |= 0x41;
915 0 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
916 0 : getRootFrm()->InvalidateBrowseWidth();
917 0 : SwRect aNew( GetObjRectWithSpaces() );
918 0 : SwRect aOld( maFrm );
919 0 : if ( RES_UL_SPACE == nWhich )
920 : {
921 0 : const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
922 0 : aOld.Top( std::max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
923 0 : aOld.SSize().Height()+= rUL.GetLower();
924 : }
925 : else
926 : {
927 0 : const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
928 0 : aOld.Left ( std::max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
929 0 : aOld.SSize().Width() += rLR.GetRight();
930 : }
931 0 : aNew.Union( aOld );
932 0 : NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
933 : }
934 0 : break;
935 :
936 : case RES_TEXT_VERT_ADJUST:
937 : {
938 0 : InvalidateContentPos();
939 0 : rInvFlags |= 0x10;
940 : }
941 0 : break;
942 :
943 : case RES_BOX:
944 : case RES_SHADOW:
945 0 : rInvFlags |= 0x17;
946 0 : break;
947 :
948 : case RES_FRAMEDIR :
949 1 : SetDerivedVert( sal_False );
950 1 : SetDerivedR2L( sal_False );
951 1 : CheckDirChange();
952 1 : break;
953 :
954 : case RES_OPAQUE:
955 : {
956 0 : if ( pSh )
957 0 : pSh->InvalidateWindows( Frm() );
958 :
959 0 : const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
960 0 : const sal_uInt8 nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
961 0 : pIDDMA->GetHeavenId() :
962 0 : pIDDMA->GetHellId();
963 0 : GetVirtDrawObj()->SetLayer( nId );
964 0 : if( pSh )
965 : {
966 0 : SwRootFrm* pLayout = getRootFrm();
967 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
968 : {
969 0 : pSh->Imp()->DisposeAccessibleFrm( this );
970 0 : pSh->Imp()->AddAccessibleFrm( this );
971 : }
972 : }
973 : // #i28701# - perform reorder of object lists
974 : // at anchor frame and at page frame.
975 0 : rInvFlags |= 0x80;
976 : }
977 0 : break;
978 :
979 : case RES_URL:
980 : // The interface changes the frame size when interacting with text frames,
981 : // the Map, however, needs to be relative to FrmSize().
982 3 : if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
983 1 : ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
984 : {
985 0 : const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
986 0 : if ( rSz.GetHeight() != Frm().Height() ||
987 0 : rSz.GetWidth() != Frm().Width() )
988 : {
989 0 : SwFmtURL aURL( GetFmt()->GetURL() );
990 0 : Fraction aScaleX( Frm().Width(), rSz.GetWidth() );
991 0 : Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
992 0 : aURL.GetMap()->Scale( aScaleX, aScaleY );
993 0 : SwFrmFmt *pFmt = GetFmt();
994 0 : pFmt->LockModify();
995 0 : pFmt->SetFmtAttr( aURL );
996 0 : pFmt->UnlockModify();
997 : }
998 : }
999 : // No invalidation necessary
1000 1 : break;
1001 :
1002 : case RES_CHAIN:
1003 : {
1004 0 : SwFmtChain *pChain = (SwFmtChain*)pNew;
1005 0 : if ( pChain->GetNext() )
1006 : {
1007 0 : SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
1008 0 : if ( GetNextLink() && pFollow != GetNextLink() )
1009 0 : SwFlyFrm::UnchainFrames( this, GetNextLink());
1010 0 : if ( pFollow )
1011 : {
1012 0 : if ( pFollow->GetPrevLink() &&
1013 0 : pFollow->GetPrevLink() != this )
1014 : SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
1015 0 : pFollow );
1016 0 : if ( !GetNextLink() )
1017 0 : SwFlyFrm::ChainFrames( this, pFollow );
1018 : }
1019 : }
1020 0 : else if ( GetNextLink() )
1021 0 : SwFlyFrm::UnchainFrames( this, GetNextLink() );
1022 0 : if ( pChain->GetPrev() )
1023 : {
1024 0 : SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
1025 0 : if ( GetPrevLink() && pMaster != GetPrevLink() )
1026 0 : SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1027 0 : if ( pMaster )
1028 : {
1029 0 : if ( pMaster->GetNextLink() &&
1030 0 : pMaster->GetNextLink() != this )
1031 : SwFlyFrm::UnchainFrames( pMaster,
1032 0 : pMaster->GetNextLink() );
1033 0 : if ( !GetPrevLink() )
1034 0 : SwFlyFrm::ChainFrames( pMaster, this );
1035 : }
1036 : }
1037 0 : else if ( GetPrevLink() )
1038 0 : SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1039 : }
1040 : //fall-through
1041 : default:
1042 109 : bClear = false;
1043 : }
1044 259 : if ( bClear )
1045 : {
1046 150 : if ( pOldSet || pNewSet )
1047 : {
1048 131 : if ( pOldSet )
1049 131 : pOldSet->ClearItem( nWhich );
1050 262 : if ( pNewSet )
1051 131 : pNewSet->ClearItem( nWhich );
1052 : }
1053 : else
1054 19 : SwLayoutFrm::Modify( pOld, pNew );
1055 : }
1056 259 : }
1057 :
1058 : /// Gets information from the Modify
1059 26 : bool SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
1060 : {
1061 26 : if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
1062 26 : return false; // There's a FlyFrm, so use it
1063 0 : return true; // Continue searching
1064 : }
1065 :
1066 3916 : void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
1067 : {
1068 3916 : InvalidatePage( pPage );
1069 3916 : bNotifyBack = bInvalid = sal_True;
1070 :
1071 : SwFlyFrm *pFrm;
1072 3916 : if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) )
1073 : {
1074 : // Very bad case: If the Fly is bound within another Fly which
1075 : // contains columns, the Format should be from that one.
1076 228 : if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
1077 171 : pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
1078 0 : pFrm->InvalidateSize();
1079 : }
1080 :
1081 : // #i85216#
1082 : // if vertical position is oriented at a layout frame inside a ghost section,
1083 : // assure that the position is invalidated and that the information about
1084 : // the vertical position oriented frame is cleared
1085 3916 : if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() )
1086 : {
1087 1930 : const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() );
1088 1930 : if ( pSectFrm && pSectFrm->GetSection() == 0 )
1089 : {
1090 0 : InvalidatePos();
1091 0 : ClearVertPosOrientFrm();
1092 : }
1093 : }
1094 3916 : }
1095 :
1096 : /** Change the relative position
1097 : *
1098 : * The position will be Fix automatically and the attribute is changed accordingly.
1099 : */
1100 0 : void SwFlyFrm::ChgRelPos( const Point &rNewPos )
1101 : {
1102 0 : if ( GetCurrRelPos() != rNewPos )
1103 : {
1104 0 : SwFrmFmt *pFmt = GetFmt();
1105 0 : const bool bVert = GetAnchorFrm()->IsVertical();
1106 0 : const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y();
1107 0 : SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY;
1108 0 : if( bVert )
1109 0 : nTmpY = -nTmpY;
1110 0 : SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
1111 0 : RES_VERT_ORIENT, RES_HORI_ORIENT);
1112 :
1113 0 : SwFmtVertOrient aVert( pFmt->GetVertOrient() );
1114 0 : SwTxtFrm *pAutoFrm = NULL;
1115 : // #i34948# - handle also at-page and at-fly anchored
1116 : // Writer fly frames
1117 0 : const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId();
1118 0 : if ( eAnchorType == FLY_AT_PAGE )
1119 : {
1120 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1121 0 : aVert.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1122 : }
1123 0 : else if ( eAnchorType == FLY_AT_FLY )
1124 : {
1125 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1126 0 : aVert.SetRelationOrient( text::RelOrientation::FRAME );
1127 : }
1128 0 : else if ( IsFlyAtCntFrm() || text::VertOrientation::NONE != aVert.GetVertOrient() )
1129 : {
1130 0 : if( text::RelOrientation::CHAR == aVert.GetRelationOrient() && IsAutoPos() )
1131 : {
1132 0 : if( LONG_MAX != nNewY )
1133 : {
1134 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1135 : sal_Int32 nOfs =
1136 0 : pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
1137 : OSL_ENSURE( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" );
1138 0 : pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1139 0 : while( pAutoFrm->GetFollow() &&
1140 0 : pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1141 : {
1142 0 : if( pAutoFrm == GetAnchorFrm() )
1143 0 : nTmpY += pAutoFrm->GetRelPos().Y();
1144 0 : nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
1145 0 : pAutoFrm = pAutoFrm->GetFollow();
1146 : }
1147 0 : nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
1148 : }
1149 : else
1150 0 : aVert.SetVertOrient( text::VertOrientation::CHAR_BOTTOM );
1151 : }
1152 : else
1153 : {
1154 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1155 0 : aVert.SetRelationOrient( text::RelOrientation::FRAME );
1156 : }
1157 : }
1158 0 : aVert.SetPos( nTmpY );
1159 0 : aSet.Put( aVert );
1160 :
1161 : // For Flys in the Cnt, the horizontal orientation is of no interest,
1162 : // as it's always 0
1163 0 : if ( !IsFlyInCntFrm() )
1164 : {
1165 0 : const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X();
1166 0 : SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX;
1167 0 : SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
1168 : // #i34948# - handle also at-page and at-fly anchored
1169 : // Writer fly frames
1170 0 : if ( eAnchorType == FLY_AT_PAGE )
1171 : {
1172 0 : aHori.SetHoriOrient( text::HoriOrientation::NONE );
1173 0 : aHori.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1174 0 : aHori.SetPosToggle( sal_False );
1175 : }
1176 0 : else if ( eAnchorType == FLY_AT_FLY )
1177 : {
1178 0 : aHori.SetHoriOrient( text::HoriOrientation::NONE );
1179 0 : aHori.SetRelationOrient( text::RelOrientation::FRAME );
1180 0 : aHori.SetPosToggle( sal_False );
1181 : }
1182 0 : else if ( IsFlyAtCntFrm() || text::HoriOrientation::NONE != aHori.GetHoriOrient() )
1183 : {
1184 0 : aHori.SetHoriOrient( text::HoriOrientation::NONE );
1185 0 : if( text::RelOrientation::CHAR == aHori.GetRelationOrient() && IsAutoPos() )
1186 : {
1187 0 : if( LONG_MAX != nNewX )
1188 : {
1189 0 : if( !pAutoFrm )
1190 : {
1191 0 : sal_Int32 nOfs = pFmt->GetAnchor().GetCntntAnchor()
1192 0 : ->nContent.GetIndex();
1193 : OSL_ENSURE( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected");
1194 0 : pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1195 0 : while( pAutoFrm->GetFollow() &&
1196 0 : pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1197 0 : pAutoFrm = pAutoFrm->GetFollow();
1198 : }
1199 0 : nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
1200 : }
1201 : }
1202 : else
1203 0 : aHori.SetRelationOrient( text::RelOrientation::FRAME );
1204 0 : aHori.SetPosToggle( sal_False );
1205 : }
1206 0 : aHori.SetPos( nTmpX );
1207 0 : aSet.Put( aHori );
1208 : }
1209 0 : SetCurrRelPos( rNewPos );
1210 0 : pFmt->GetDoc()->SetAttr( aSet, *pFmt );
1211 : }
1212 0 : }
1213 :
1214 : /** "Formats" the Frame; Frm and PrtArea.
1215 : *
1216 : * The FixSize is not inserted here.
1217 : */
1218 3748 : void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
1219 : {
1220 : OSL_ENSURE( pAttrs, "FlyFrm::Format, pAttrs is 0." );
1221 :
1222 3748 : ColLock();
1223 :
1224 3748 : if ( !mbValidSize )
1225 : {
1226 3748 : if ( Frm().Top() == FAR_AWAY && Frm().Left() == FAR_AWAY )
1227 : {
1228 : // Remove safety switch (see SwFrm::CTor)
1229 1147 : Frm().Pos().setX(0);
1230 1147 : Frm().Pos().setY(0);
1231 : // #i68520#
1232 1147 : InvalidateObjRectWithSpaces();
1233 : }
1234 :
1235 : // Check column width and set it if needed
1236 3748 : if ( Lower() && Lower()->IsColumnFrm() )
1237 0 : AdjustColumns( 0, sal_False );
1238 :
1239 3748 : mbValidSize = sal_True;
1240 :
1241 3748 : const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
1242 3748 : const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
1243 3748 : const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
1244 3748 : Size aRelSize( CalcRel( rFrmSz ) );
1245 :
1246 : OSL_ENSURE( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "FrameAttr height is 0." );
1247 : OSL_ENSURE( pAttrs->GetSize().Width() != 0 || rFrmSz.GetWidthPercent(), "FrameAttr width is 0." );
1248 :
1249 3748 : SWRECTFN( this )
1250 3748 : if( !HasFixSize() )
1251 : {
1252 1855 : long nMinHeight = 0;
1253 1855 : if( IsMinHeight() )
1254 112 : nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1255 :
1256 1855 : SwTwips nRemaining = CalcContentHeight(pAttrs, nMinHeight, nUL);
1257 1855 : if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
1258 67 : nRemaining = nMinHeight - nUL;
1259 : // Because the Grow/Shrink of the Flys does not directly
1260 : // set the size - only indirectly by triggering a Format()
1261 : // via Invalidate() - the sizes need to be set here.
1262 : // Notification is running along already.
1263 : // As we already got a lot of zeros per attribute, we block them
1264 : // from now on.
1265 :
1266 1855 : if ( nRemaining < MINFLY )
1267 535 : nRemaining = MINFLY;
1268 :
1269 1855 : (Prt().*fnRect->fnSetHeight)( nRemaining );
1270 1855 : nRemaining -= (Frm().*fnRect->fnGetHeight)();
1271 1855 : (Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
1272 : // #i68520#
1273 1855 : if ( nRemaining + nUL != 0 )
1274 : {
1275 883 : InvalidateObjRectWithSpaces();
1276 : }
1277 1855 : mbValidSize = sal_True;
1278 : }
1279 : else
1280 : {
1281 1893 : mbValidSize = sal_True; // Fixed Frms do not Format itself
1282 : // Flys set their size using the attr
1283 1893 : SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
1284 1893 : nNewSize -= nUL;
1285 1893 : if( nNewSize < MINFLY )
1286 16 : nNewSize = MINFLY;
1287 1893 : (Prt().*fnRect->fnSetHeight)( nNewSize );
1288 1893 : nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
1289 1893 : (Frm().*fnRect->fnAddBottom)( nNewSize );
1290 : // #i68520#
1291 1893 : if ( nNewSize != 0 )
1292 : {
1293 572 : InvalidateObjRectWithSpaces();
1294 : }
1295 : }
1296 :
1297 3748 : if ( !bFormatHeightOnly )
1298 : {
1299 : OSL_ENSURE( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" );
1300 3613 : SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
1301 :
1302 3613 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1303 : {
1304 : // #i9046# Autowidth for fly frames
1305 390 : const SwTwips nAutoWidth = CalcAutoWidth();
1306 390 : if ( nAutoWidth )
1307 : {
1308 390 : if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
1309 390 : nNewSize = std::max( nNewSize - nLR, nAutoWidth );
1310 : else
1311 0 : nNewSize = nAutoWidth;
1312 : }
1313 : }
1314 : else
1315 3223 : nNewSize -= nLR;
1316 :
1317 3613 : if( nNewSize < MINFLY )
1318 16 : nNewSize = MINFLY;
1319 3613 : (Prt().*fnRect->fnSetWidth)( nNewSize );
1320 3613 : nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
1321 3613 : (Frm().*fnRect->fnAddRight)( nNewSize );
1322 : // #i68520#
1323 3613 : if ( nNewSize != 0 )
1324 : {
1325 128 : InvalidateObjRectWithSpaces();
1326 : }
1327 : }
1328 : }
1329 3748 : ColUnlock();
1330 3748 : }
1331 :
1332 : // OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
1333 : // default value = false.
1334 : // OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
1335 : // default value = false.
1336 : // OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
1337 : // <FormatWidthCols(..)> to avoid follow formatting
1338 : // for text frames. But, unformatted follows causes
1339 : // problems in method <SwCntntFrm::_WouldFit(..)>,
1340 : // which assumes that the follows are formatted.
1341 : // Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
1342 786 : void CalcCntnt( SwLayoutFrm *pLay,
1343 : bool bNoColl,
1344 : bool bNoCalcFollow )
1345 : {
1346 : SwSectionFrm* pSect;
1347 786 : bool bCollect = false;
1348 786 : if( pLay->IsSctFrm() )
1349 : {
1350 786 : pSect = (SwSectionFrm*)pLay;
1351 786 : if( pSect->IsEndnAtEnd() && !bNoColl )
1352 : {
1353 0 : bCollect = true;
1354 0 : SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
1355 : }
1356 786 : pSect->CalcFtnCntnt();
1357 : }
1358 : else
1359 0 : pSect = NULL;
1360 786 : SwFrm *pFrm = pLay->ContainsAny();
1361 786 : if ( !pFrm )
1362 : {
1363 78 : if( pSect )
1364 : {
1365 78 : if( pSect->HasFollow() )
1366 47 : pFrm = pSect->GetFollow()->ContainsAny();
1367 78 : if( !pFrm )
1368 : {
1369 31 : if( pSect->IsEndnAtEnd() )
1370 : {
1371 0 : if( bCollect )
1372 0 : pLay->GetFmt()->GetDoc()->GetLayouter()->
1373 0 : InsertEndnotes( pSect );
1374 0 : sal_Bool bLock = pSect->IsFtnLock();
1375 0 : pSect->SetFtnLock( true );
1376 0 : pSect->CalcFtnCntnt();
1377 0 : pSect->CalcFtnCntnt();
1378 0 : pSect->SetFtnLock( bLock );
1379 : }
1380 31 : return;
1381 : }
1382 47 : pFrm->_InvalidatePos();
1383 : }
1384 : else
1385 0 : return;
1386 : }
1387 755 : pFrm->InvalidatePage();
1388 :
1389 : do
1390 : {
1391 : // local variables to avoid loops caused by anchored object positioning
1392 755 : SwAnchoredObject* pAgainObj1 = 0;
1393 755 : SwAnchoredObject* pAgainObj2 = 0;
1394 :
1395 : // FME 2007-08-30 #i81146# new loop control
1396 755 : sal_uInt16 nLoopControlRuns = 0;
1397 755 : const sal_uInt16 nLoopControlMax = 20;
1398 755 : const SwFrm* pLoopControlCond = 0;
1399 :
1400 : SwFrm* pLast;
1401 4695 : do
1402 : {
1403 4695 : pLast = pFrm;
1404 9390 : if( pFrm->IsVertical() ?
1405 0 : ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
1406 4695 : : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
1407 : {
1408 312 : pFrm->Prepare( PREP_FIXSIZE_CHG );
1409 312 : pFrm->_InvalidateSize();
1410 : }
1411 :
1412 4695 : if ( pFrm->IsTabFrm() )
1413 : {
1414 21 : ((SwTabFrm*)pFrm)->bCalcLowers = sal_True;
1415 : // OD 26.08.2003 #i18103# - lock move backward of follow table,
1416 : // if no section content is formatted or follow table belongs
1417 : // to the section, which content is formatted.
1418 21 : if ( ((SwTabFrm*)pFrm)->IsFollow() &&
1419 0 : ( !pSect || pSect == pFrm->FindSctFrm() ) )
1420 : {
1421 0 : ((SwTabFrm*)pFrm)->bLockBackMove = sal_True;
1422 : }
1423 : }
1424 :
1425 : // OD 14.03.2003 #i11760# - forbid format of follow, if requested.
1426 4695 : if ( bNoCalcFollow && pFrm->IsTxtFrm() )
1427 0 : static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
1428 :
1429 4695 : pFrm->Calc();
1430 :
1431 : // OD 14.03.2003 #i11760# - reset control flag for follow format.
1432 4695 : if ( pFrm->IsTxtFrm() )
1433 : {
1434 4674 : static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat();
1435 : }
1436 :
1437 : // #111937# The keep-attribute can cause the position
1438 : // of the prev to be invalid:
1439 : // OD 2004-03-15 #116560# - Do not consider invalid previous frame
1440 : // due to its keep-attribute, if current frame is a follow or is locked.
1441 : // #i44049# - do not consider invalid previous
1442 : // frame due to its keep-attribute, if it can't move forward.
1443 : // #i57765# - do not consider invalid previous
1444 : // frame, if current frame has a column/page break before attribute.
1445 4695 : SwFrm* pTmpPrev = pFrm->FindPrev();
1446 4695 : SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
1447 4695 : SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
1448 :
1449 9038 : bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
1450 8947 : !pTmpFlowFrm->IsFollow() &&
1451 8856 : !StackHack::IsLocked() && // #i76382#
1452 8636 : !pTmpFlowFrm->IsJoinLocked() &&
1453 4210 : !pTmpPrev->GetValidPosFlag() &&
1454 4 : pLay->IsAnLower( pTmpPrev ) &&
1455 4697 : pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
1456 4695 : pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
1457 :
1458 : // format floating screen objects anchored to the frame.
1459 4695 : bool bRestartLayoutProcess = false;
1460 4695 : if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
1461 : {
1462 7 : bool bAgain = false;
1463 7 : SwPageFrm* pPageFrm = pFrm->FindPageFrm();
1464 7 : sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
1465 17 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
1466 : {
1467 : // #i28701#
1468 10 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
1469 : // determine, if anchored object has to be formatted.
1470 10 : if ( pAnchoredObj->PositionLocked() )
1471 : {
1472 0 : continue;
1473 : }
1474 :
1475 : // format anchored object
1476 10 : if ( pAnchoredObj->IsFormatPossible() )
1477 : {
1478 : // #i43737# - no invalidation of
1479 : // anchored object needed - causes loops for as-character
1480 : // anchored objects.
1481 : //pAnchoredObj->InvalidateObjPos();
1482 10 : SwRect aRect( pAnchoredObj->GetObjRect() );
1483 10 : if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) )
1484 : {
1485 0 : bRestartLayoutProcess = true;
1486 0 : break;
1487 : }
1488 : // #i3317# - restart layout process,
1489 : // if the position of the anchored object is locked now.
1490 10 : if ( pAnchoredObj->PositionLocked() )
1491 : {
1492 0 : bRestartLayoutProcess = true;
1493 0 : break;
1494 : }
1495 :
1496 10 : if ( aRect != pAnchoredObj->GetObjRect() )
1497 : {
1498 0 : bAgain = true;
1499 0 : if ( pAgainObj2 == pAnchoredObj )
1500 : {
1501 : OSL_FAIL( "::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" );
1502 : // Prevent oscillation
1503 0 : SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1504 0 : SwFmtSurround aAttr( rFmt.GetSurround() );
1505 0 : if( SURROUND_THROUGHT != aAttr.GetSurround() )
1506 : {
1507 : // When on auto position, we can only set it to
1508 : // flow through
1509 0 : if ((rFmt.GetAnchor().GetAnchorId() ==
1510 0 : FLY_AT_CHAR) &&
1511 : (SURROUND_PARALLEL ==
1512 0 : aAttr.GetSurround()))
1513 : {
1514 0 : aAttr.SetSurround( SURROUND_THROUGHT );
1515 : }
1516 : else
1517 : {
1518 0 : aAttr.SetSurround( SURROUND_PARALLEL );
1519 : }
1520 0 : rFmt.LockModify();
1521 0 : rFmt.SetFmtAttr( aAttr );
1522 0 : rFmt.UnlockModify();
1523 0 : }
1524 : }
1525 : else
1526 : {
1527 0 : if ( pAgainObj1 == pAnchoredObj )
1528 0 : pAgainObj2 = pAnchoredObj;
1529 0 : pAgainObj1 = pAnchoredObj;
1530 : }
1531 : }
1532 :
1533 10 : if ( !pFrm->GetDrawObjs() )
1534 0 : break;
1535 10 : if ( pFrm->GetDrawObjs()->Count() < nCnt )
1536 : {
1537 0 : --i;
1538 0 : --nCnt;
1539 : }
1540 : }
1541 : }
1542 :
1543 : // #i28701# - restart layout process, if
1544 : // requested by floating screen object formatting
1545 7 : if ( bRestartLayoutProcess )
1546 : {
1547 0 : pFrm = pLay->ContainsAny();
1548 0 : pAgainObj1 = 0L;
1549 0 : pAgainObj2 = 0L;
1550 0 : continue;
1551 : }
1552 :
1553 : // OD 2004-05-17 #i28701# - format anchor frame after its objects
1554 : // are formatted, if the wrapping style influence has to be considered.
1555 7 : if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1556 : {
1557 0 : pFrm->Calc();
1558 : }
1559 :
1560 7 : if ( bAgain )
1561 : {
1562 0 : pFrm = pLay->ContainsCntnt();
1563 0 : if ( pFrm && pFrm->IsInTab() )
1564 0 : pFrm = pFrm->FindTabFrm();
1565 0 : if( pFrm && pFrm->IsInSct() )
1566 : {
1567 0 : SwSectionFrm* pTmp = pFrm->FindSctFrm();
1568 0 : if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
1569 0 : pFrm = pTmp;
1570 : }
1571 :
1572 0 : if ( pFrm == pLoopControlCond )
1573 0 : ++nLoopControlRuns;
1574 : else
1575 : {
1576 0 : nLoopControlRuns = 0;
1577 0 : pLoopControlCond = pFrm;
1578 : }
1579 :
1580 0 : if ( nLoopControlRuns < nLoopControlMax )
1581 0 : continue;
1582 :
1583 : OSL_FAIL( "LoopControl in CalcCntnt" );
1584 : }
1585 : }
1586 4695 : if ( pFrm->IsTabFrm() )
1587 : {
1588 21 : if ( ((SwTabFrm*)pFrm)->IsFollow() )
1589 0 : ((SwTabFrm*)pFrm)->bLockBackMove = sal_False;
1590 : }
1591 :
1592 4695 : pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
1593 4695 : if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
1594 : {
1595 : // Empty SectionFrms could be present here
1596 2964 : while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
1597 1468 : pFrm = pFrm->FindNext();
1598 :
1599 : // If FindNext returns the Follow of the original Area, we want to
1600 : // continue with this content as long as it flows back.
1601 1029 : if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
1602 281 : ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
1603 : {
1604 231 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1605 231 : if( pFrm )
1606 223 : pFrm->_InvalidatePos();
1607 : }
1608 : }
1609 : // Stay in the pLay
1610 : // Except for SectionFrms with Follow: the first CntntFrm of the Follow
1611 : // will be formatted, so that it get's a chance to load in the pLay.
1612 : // As long as these Frames are loading in pLay, we continue
1613 13011 : } while ( pFrm &&
1614 5027 : ( pLay->IsAnLower( pFrm ) ||
1615 651 : ( pSect &&
1616 987 : ( ( pSect->HasFollow() &&
1617 457 : ( pLay->IsAnLower( pLast ) ||
1618 242 : ( pLast->IsInSct() &&
1619 336 : pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
1620 651 : pSect->GetFollow()->IsAnLower( pFrm ) ) ||
1621 777 : ( pFrm->IsInSct() &&
1622 341 : pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
1623 755 : if( pSect )
1624 : {
1625 755 : if( bCollect )
1626 : {
1627 0 : pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
1628 0 : pSect->CalcFtnCntnt();
1629 : }
1630 755 : if( pSect->HasFollow() )
1631 : {
1632 194 : SwSectionFrm* pNxt = pSect->GetFollow();
1633 388 : while( pNxt && !pNxt->ContainsCntnt() )
1634 0 : pNxt = pNxt->GetFollow();
1635 194 : if( pNxt )
1636 194 : pNxt->CalcFtnCntnt();
1637 : }
1638 755 : if( bCollect )
1639 : {
1640 0 : pFrm = pLay->ContainsAny();
1641 0 : bCollect = false;
1642 0 : if( pFrm )
1643 0 : continue;
1644 : }
1645 : }
1646 755 : break;
1647 : }
1648 0 : while( true );
1649 : }
1650 :
1651 : // OD 2004-03-23 #i26791#
1652 79 : void SwFlyFrm::MakeObjPos()
1653 : {
1654 79 : if ( !mbValidPos )
1655 : {
1656 79 : mbValidPos = sal_True;
1657 :
1658 : // OD 29.10.2003 #113049# - use new class to position object
1659 79 : GetAnchorFrm()->Calc();
1660 : objectpositioning::SwToLayoutAnchoredObjectPosition
1661 79 : aObjPositioning( *GetVirtDrawObj() );
1662 79 : aObjPositioning.CalcPosition();
1663 :
1664 : // #i58280#
1665 : // update relative position
1666 79 : SetCurrRelPos( aObjPositioning.GetRelPos() );
1667 :
1668 79 : SWRECTFN( GetAnchorFrm() );
1669 79 : maFrm.Pos( aObjPositioning.GetRelPos() );
1670 79 : maFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
1671 : // #i69335#
1672 79 : InvalidateObjRectWithSpaces();
1673 : }
1674 79 : }
1675 :
1676 3748 : void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
1677 : {
1678 3748 : if ( !mbValidPrtArea )
1679 : {
1680 3748 : mbValidPrtArea = sal_True;
1681 :
1682 : // OD 31.07.2003 #110978# - consider vertical layout
1683 3748 : SWRECTFN( this )
1684 3748 : (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
1685 7496 : rAttrs.CalcRightLine() );
1686 3748 : (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
1687 7496 : rAttrs.CalcBottomLine() );
1688 : }
1689 3748 : }
1690 :
1691 3914 : void SwFlyFrm::MakeContentPos( const SwBorderAttrs &rAttrs )
1692 : {
1693 3914 : if ( !m_bValidContentPos )
1694 : {
1695 3914 : m_bValidContentPos = true;
1696 :
1697 3914 : const SwTwips nUL = rAttrs.CalcTopLine() + rAttrs.CalcBottomLine();
1698 3914 : Size aRelSize( CalcRel( GetFmt()->GetFrmSize() ) );
1699 :
1700 3914 : SWRECTFN( this )
1701 3914 : long nMinHeight = 0;
1702 3914 : if( IsMinHeight() )
1703 112 : nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1704 :
1705 3914 : Point aNewContentPos;
1706 3914 : aNewContentPos = Prt().Pos();
1707 3914 : const SdrTextVertAdjust nAdjust = GetFmt()->GetTextVertAdjust().GetValue();
1708 3914 : if( nAdjust != SDRTEXTVERTADJUST_TOP )
1709 : {
1710 668 : SwTwips nDiff = (Prt().*fnRect->fnGetHeight)() - CalcContentHeight(&rAttrs, nMinHeight, nUL);
1711 668 : if( nDiff > 0 )
1712 : {
1713 518 : if( nAdjust == SDRTEXTVERTADJUST_CENTER )
1714 : {
1715 473 : if( bVertL2R )
1716 0 : aNewContentPos.setX(aNewContentPos.getX() + nDiff/2);
1717 473 : else if( bVert )
1718 0 : aNewContentPos.setX(aNewContentPos.getX() - nDiff/2);
1719 : else
1720 473 : aNewContentPos.setY(aNewContentPos.getY() + nDiff/2);
1721 : }
1722 45 : else if( nAdjust == SDRTEXTVERTADJUST_BOTTOM )
1723 : {
1724 45 : if( bVertL2R )
1725 0 : aNewContentPos.setX(aNewContentPos.getX() + nDiff);
1726 45 : else if( bVert )
1727 0 : aNewContentPos.setX(aNewContentPos.getX() - nDiff);
1728 : else
1729 45 : aNewContentPos.setY(aNewContentPos.getY() + nDiff);
1730 : }
1731 : }
1732 : }
1733 3914 : if( aNewContentPos != ContentPos() )
1734 : {
1735 612 : ContentPos() = aNewContentPos;
1736 1496 : for( SwFrm *pFrm = Lower(); pFrm; pFrm = pFrm->GetNext())
1737 : {
1738 884 : pFrm->InvalidatePos();
1739 : }
1740 : }
1741 : }
1742 3914 : }
1743 :
1744 337 : void SwFlyFrm::InvalidateContentPos()
1745 : {
1746 337 : m_bValidContentPos = false;
1747 337 : _Invalidate();
1748 337 : }
1749 :
1750 961 : SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst )
1751 : {
1752 961 : SWRECTFN( this )
1753 961 : if ( Lower() && !IsColLocked() && !HasFixSize() )
1754 : {
1755 742 : SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
1756 742 : if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
1757 0 : nDist = LONG_MAX - nSize;
1758 :
1759 742 : if ( nDist <= 0L )
1760 0 : return 0L;
1761 :
1762 742 : if ( Lower()->IsColumnFrm() )
1763 : { // If it's a Column Frame, the Format takes control of the
1764 : // resizing (due to the adjustment).
1765 0 : if ( !bTst )
1766 : {
1767 : // #i28701# - unlock position of Writer fly frame
1768 0 : UnlockPosition();
1769 0 : _InvalidatePos();
1770 0 : InvalidateSize();
1771 : }
1772 0 : return 0L;
1773 : }
1774 :
1775 742 : if ( !bTst )
1776 : {
1777 742 : const SwRect aOld( GetObjRectWithSpaces() );
1778 742 : _InvalidateSize();
1779 742 : const sal_Bool bOldLock = bLocked;
1780 742 : Unlock();
1781 742 : if ( IsFlyFreeFrm() )
1782 : {
1783 : // #i37068# - no format of position here
1784 : // and prevent move in method <CheckClip(..)>.
1785 : // This is needed to prevent layout loop caused by nested
1786 : // Writer fly frames - inner Writer fly frames format its
1787 : // anchor, which grows/shrinks the outer Writer fly frame.
1788 : // Note: position will be invalidated below.
1789 723 : mbValidPos = sal_True;
1790 : // #i55416#
1791 : // Suppress format of width for autowidth frame, because the
1792 : // format of the width would call <SwTxtFrm::CalcFitToContent()>
1793 : // for the lower frame, which initiated this grow.
1794 723 : const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
1795 723 : const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
1796 723 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1797 : {
1798 132 : bFormatHeightOnly = sal_True;
1799 : }
1800 723 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
1801 723 : ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
1802 723 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
1803 : // #i55416#
1804 723 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1805 : {
1806 132 : bFormatHeightOnly = bOldFormatHeightOnly;
1807 : }
1808 : }
1809 : else
1810 19 : MakeAll();
1811 742 : _InvalidateSize();
1812 742 : InvalidatePos();
1813 742 : if ( bOldLock )
1814 0 : Lock();
1815 742 : const SwRect aNew( GetObjRectWithSpaces() );
1816 742 : if ( aOld != aNew )
1817 571 : ::Notify( this, FindPageFrm(), aOld );
1818 742 : return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
1819 : }
1820 0 : return nDist;
1821 : }
1822 219 : return 0L;
1823 : }
1824 :
1825 21 : SwTwips SwFlyFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
1826 : {
1827 21 : if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
1828 : {
1829 17 : SWRECTFN( this )
1830 17 : SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
1831 17 : if ( nDist > nHeight )
1832 0 : nDist = nHeight;
1833 :
1834 17 : SwTwips nVal = nDist;
1835 17 : if ( IsMinHeight() )
1836 : {
1837 1 : const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
1838 1 : SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
1839 :
1840 1 : nVal = std::min( nDist, nHeight - nFmtHeight );
1841 : }
1842 :
1843 17 : if ( nVal <= 0L )
1844 0 : return 0L;
1845 :
1846 17 : if ( Lower()->IsColumnFrm() )
1847 : { // If it's a Column Frame, the Format takes control of the
1848 : // resizing (due to the adjustment).
1849 0 : if ( !bTst )
1850 : {
1851 0 : SwRect aOld( GetObjRectWithSpaces() );
1852 0 : (Frm().*fnRect->fnSetHeight)( nHeight - nVal );
1853 : // #i68520#
1854 0 : if ( nHeight - nVal != 0 )
1855 : {
1856 0 : InvalidateObjRectWithSpaces();
1857 : }
1858 0 : nHeight = (Prt().*fnRect->fnGetHeight)();
1859 0 : (Prt().*fnRect->fnSetHeight)( nHeight - nVal );
1860 0 : _InvalidatePos();
1861 0 : InvalidateSize();
1862 0 : ::Notify( this, FindPageFrm(), aOld );
1863 0 : NotifyDrawObj();
1864 0 : if ( GetAnchorFrm()->IsInFly() )
1865 0 : AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
1866 : }
1867 0 : return 0L;
1868 : }
1869 :
1870 17 : if ( !bTst )
1871 : {
1872 17 : const SwRect aOld( GetObjRectWithSpaces() );
1873 17 : _InvalidateSize();
1874 17 : const sal_Bool bOldLocked = bLocked;
1875 17 : Unlock();
1876 17 : if ( IsFlyFreeFrm() )
1877 : {
1878 : // #i37068# - no format of position here
1879 : // and prevent move in method <CheckClip(..)>.
1880 : // This is needed to prevent layout loop caused by nested
1881 : // Writer fly frames - inner Writer fly frames format its
1882 : // anchor, which grows/shrinks the outer Writer fly frame.
1883 : // Note: position will be invalidated below.
1884 17 : mbValidPos = sal_True;
1885 : // #i55416#
1886 : // Suppress format of width for autowidth frame, because the
1887 : // format of the width would call <SwTxtFrm::CalcFitToContent()>
1888 : // for the lower frame, which initiated this shrink.
1889 17 : const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
1890 17 : const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
1891 17 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1892 : {
1893 3 : bFormatHeightOnly = sal_True;
1894 : }
1895 17 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
1896 17 : ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
1897 17 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
1898 : // #i55416#
1899 17 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1900 : {
1901 3 : bFormatHeightOnly = bOldFormatHeightOnly;
1902 : }
1903 : }
1904 : else
1905 0 : MakeAll();
1906 17 : _InvalidateSize();
1907 17 : InvalidatePos();
1908 17 : if ( bOldLocked )
1909 0 : Lock();
1910 17 : const SwRect aNew( GetObjRectWithSpaces() );
1911 17 : if ( aOld != aNew )
1912 : {
1913 8 : ::Notify( this, FindPageFrm(), aOld );
1914 8 : if ( GetAnchorFrm()->IsInFly() )
1915 0 : AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
1916 : }
1917 17 : return (aOld.*fnRect->fnGetHeight)() -
1918 17 : (aNew.*fnRect->fnGetHeight)();
1919 : }
1920 0 : return nVal;
1921 : }
1922 4 : return 0L;
1923 : }
1924 :
1925 30 : Size SwFlyFrm::ChgSize( const Size& aNewSize )
1926 : {
1927 : // #i53298#
1928 : // If the fly frame anchored at-paragraph or at-character contains an OLE
1929 : // object, assure that the new size fits into the current clipping area
1930 : // of the fly frame
1931 30 : Size aAdjustedNewSize( aNewSize );
1932 : {
1933 61 : if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
1934 62 : Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
1935 1 : static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
1936 : {
1937 1 : SwRect aClipRect;
1938 1 : ::CalcClipRect( GetVirtDrawObj(), aClipRect, sal_False );
1939 1 : if ( aAdjustedNewSize.Width() > aClipRect.Width() )
1940 : {
1941 0 : aAdjustedNewSize.setWidth( aClipRect.Width() );
1942 : }
1943 1 : if ( aAdjustedNewSize.Height() > aClipRect.Height() )
1944 : {
1945 0 : aAdjustedNewSize.setWidth( aClipRect.Height() );
1946 : }
1947 : }
1948 : }
1949 30 : if ( aAdjustedNewSize != Frm().SSize() )
1950 : {
1951 30 : SwFrmFmt *pFmt = GetFmt();
1952 30 : SwFmtFrmSize aSz( pFmt->GetFrmSize() );
1953 30 : aSz.SetWidth( aAdjustedNewSize.Width() );
1954 30 : aSz.SetHeight( aAdjustedNewSize.Height() );
1955 : // go via the Doc for UNDO
1956 30 : pFmt->GetDoc()->SetAttr( aSz, *pFmt );
1957 30 : return aSz.GetSize();
1958 : }
1959 : else
1960 0 : return Frm().SSize();
1961 : }
1962 :
1963 12425 : sal_Bool SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const
1964 : {
1965 : OSL_ENSURE( GetAnchorFrm(), "8-( Fly is lost in Space." );
1966 12425 : const SwFrm* pFrm = GetAnchorFrm();
1967 48613 : do
1968 : {
1969 48656 : if ( pFrm == pUpperFrm )
1970 43 : return sal_True;
1971 48613 : pFrm = pFrm->IsFlyFrm()
1972 5 : ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
1973 48618 : : pFrm->GetUpper();
1974 : } while ( pFrm );
1975 12382 : return sal_False;
1976 : }
1977 :
1978 26 : void SwFlyFrm::Cut()
1979 : {
1980 : // TODO: Implement SwFlyFrm::Cut()
1981 26 : }
1982 :
1983 1399 : void SwFrm::AppendFly( SwFlyFrm *pNew )
1984 : {
1985 1399 : if ( !mpDrawObjs )
1986 908 : mpDrawObjs = new SwSortedObjs();
1987 1399 : mpDrawObjs->Insert( *pNew );
1988 1399 : pNew->ChgAnchorFrm( this );
1989 :
1990 : // Register at the page
1991 : // If there's none present, register via SwPageFrm::PreparePage
1992 1399 : SwPageFrm *pPage = FindPageFrm();
1993 1399 : if ( pPage )
1994 : {
1995 1215 : if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == FAR_AWAY )
1996 : {
1997 : // Try to make the page formatting of new documents a bit handier:
1998 : // In the beginning we add the Flys to the back, so that the Anchors
1999 : // do not have to be reformatted unnecessarily often.
2000 : // However, we do not add them all the way at the end, so that we
2001 : // can still jump to the document's end in a meaningful way.
2002 465 : SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
2003 465 : if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) )
2004 : {
2005 462 : SwPageFrm *pTmp = pRoot->GetLastPage();
2006 462 : if ( pTmp->GetPhyPageNum() > 30 )
2007 : {
2008 110 : for ( sal_uInt16 i = 0; i < 10; ++i )
2009 : {
2010 100 : pTmp = (SwPageFrm*)pTmp->GetPrev();
2011 100 : if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
2012 0 : break; // So that we don't end up before the Anchor
2013 : }
2014 10 : if ( pTmp->IsEmptyPage() )
2015 0 : pTmp = (SwPageFrm*)pTmp->GetPrev();
2016 10 : pPage = pTmp;
2017 : }
2018 : }
2019 465 : pPage->AppendFlyToPage( pNew );
2020 : }
2021 : else
2022 750 : pPage->AppendFlyToPage( pNew );
2023 : }
2024 1399 : }
2025 :
2026 1399 : void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
2027 : {
2028 : // Deregister from the page
2029 : // Could already have happened, if the page was already destructed
2030 1399 : SwPageFrm *pPage = pToRemove->FindPageFrm();
2031 1399 : if ( pPage && pPage->GetSortedObjs() )
2032 : {
2033 199 : pPage->RemoveFlyFromPage( pToRemove );
2034 : }
2035 : // #i73201#
2036 : else
2037 : {
2038 3600 : if ( pToRemove->IsAccessibleFrm() &&
2039 2400 : pToRemove->GetFmt() &&
2040 1200 : !pToRemove->IsFlyInCntFrm() )
2041 : {
2042 620 : SwRootFrm *pRootFrm = getRootFrm();
2043 620 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
2044 : {
2045 0 : SwViewShell *pVSh = pRootFrm->GetCurrShell();
2046 0 : if( pVSh && pVSh->Imp() )
2047 : {
2048 0 : pVSh->Imp()->DisposeAccessibleFrm( pToRemove );
2049 : }
2050 : }
2051 : }
2052 : }
2053 :
2054 1399 : mpDrawObjs->Remove( *pToRemove );
2055 1399 : if ( !mpDrawObjs->Count() )
2056 916 : DELETEZ( mpDrawObjs );
2057 :
2058 1399 : pToRemove->ChgAnchorFrm( 0 );
2059 :
2060 1399 : if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
2061 9 : GetUpper()->InvalidateSize();
2062 1399 : }
2063 :
2064 974 : void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
2065 : {
2066 974 : if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
2067 : {
2068 : OSL_FAIL( "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
2069 974 : return;
2070 : }
2071 :
2072 2822 : if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
2073 974 : _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this )
2074 : {
2075 : // perform disconnect from layout, if 'master' drawing object is appended
2076 : // to a new frame.
2077 0 : static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
2078 0 : DisconnectFromLayout( false );
2079 : }
2080 :
2081 974 : if ( _rNewObj.GetAnchorFrm() != this )
2082 : {
2083 974 : if ( !mpDrawObjs )
2084 603 : mpDrawObjs = new SwSortedObjs();
2085 974 : mpDrawObjs->Insert( _rNewObj );
2086 974 : _rNewObj.ChgAnchorFrm( this );
2087 : }
2088 :
2089 : // #i113730#
2090 : // Assure the control objects and group objects containing controls are on the control layer
2091 974 : if ( ::CheckControlLayer( _rNewObj.DrawObj() ) )
2092 : {
2093 245 : const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
2094 245 : const SdrLayerID aCurrentLayer(_rNewObj.DrawObj()->GetLayer());
2095 245 : const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
2096 245 : const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
2097 :
2098 245 : if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
2099 : {
2100 0 : if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
2101 0 : aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
2102 : {
2103 0 : _rNewObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
2104 : }
2105 : else
2106 : {
2107 0 : _rNewObj.DrawObj()->SetLayer(aControlLayerID);
2108 : }
2109 : }
2110 : }
2111 :
2112 : // no direct positioning needed, but invalidate the drawing object position
2113 974 : _rNewObj.InvalidateObjPos();
2114 :
2115 : // register at page frame
2116 974 : SwPageFrm* pPage = FindPageFrm();
2117 974 : if ( pPage )
2118 : {
2119 884 : pPage->AppendDrawObjToPage( _rNewObj );
2120 : }
2121 :
2122 : // Notify accessible layout.
2123 974 : SwViewShell* pSh = getRootFrm()->GetCurrShell();
2124 974 : if( pSh )
2125 : {
2126 972 : SwRootFrm* pLayout = getRootFrm();
2127 972 : if( pLayout && pLayout->IsAnyShellAccessible() )
2128 0 : pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
2129 : }
2130 : }
2131 :
2132 974 : void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
2133 : {
2134 : // Notify accessible layout.
2135 974 : SwViewShell* pSh = getRootFrm()->GetCurrShell();
2136 974 : if( pSh )
2137 : {
2138 114 : SwRootFrm* pLayout = getRootFrm();
2139 114 : if( pLayout && pLayout->IsAnyShellAccessible() )
2140 0 : pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
2141 : }
2142 :
2143 : // deregister from page frame
2144 974 : SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
2145 974 : if ( pPage && pPage->GetSortedObjs() )
2146 75 : pPage->RemoveDrawObjFromPage( _rToRemoveObj );
2147 :
2148 974 : mpDrawObjs->Remove( _rToRemoveObj );
2149 974 : if ( !mpDrawObjs->Count() )
2150 595 : DELETEZ( mpDrawObjs );
2151 :
2152 974 : _rToRemoveObj.ChgAnchorFrm( 0 );
2153 974 : }
2154 :
2155 31010 : void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
2156 : const bool _bNoInvaOfAsCharAnchoredObjs )
2157 : {
2158 31010 : if ( GetDrawObjs() )
2159 : {
2160 : // #i26945# - determine page the frame is on,
2161 : // in order to check, if anchored object is registered at the same
2162 : // page.
2163 1399 : const SwPageFrm* pPageFrm = FindPageFrm();
2164 : // #i28701# - re-factoring
2165 1399 : sal_uInt32 i = 0;
2166 3389 : for ( ; i < GetDrawObjs()->Count(); ++i )
2167 : {
2168 1990 : SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2169 3980 : if ( _bNoInvaOfAsCharAnchoredObjs &&
2170 1990 : (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
2171 : == FLY_AS_CHAR) )
2172 : {
2173 805 : continue;
2174 : }
2175 : // #i26945# - no invalidation, if anchored object
2176 : // isn't registered at the same page and instead is registered at
2177 : // the page, where its anchor character text frame is on.
2178 2370 : if ( pAnchoredObj->GetPageFrm() &&
2179 1185 : pAnchoredObj->GetPageFrm() != pPageFrm )
2180 : {
2181 24 : SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
2182 28 : if ( pAnchorCharFrm &&
2183 4 : pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() )
2184 : {
2185 0 : continue;
2186 : }
2187 : // #115759# - unlock its position, if anchored
2188 : // object isn't registered at the page, where its anchor
2189 : // character text frame is on, respectively if it has no
2190 : // anchor character text frame.
2191 : else
2192 : {
2193 24 : pAnchoredObj->UnlockPosition();
2194 : }
2195 : }
2196 : // #i51474# - reset flag, that anchored object
2197 : // has cleared environment, and unlock its position, if the anchored
2198 : // object is registered at the same page as the anchor frame is on.
2199 2370 : if ( pAnchoredObj->ClearedEnvironment() &&
2200 1185 : pAnchoredObj->GetPageFrm() &&
2201 0 : pAnchoredObj->GetPageFrm() == pPageFrm )
2202 : {
2203 0 : pAnchoredObj->UnlockPosition();
2204 0 : pAnchoredObj->SetClearedEnvironment( false );
2205 : }
2206 : // distinguish between writer fly frames and drawing objects
2207 1185 : if ( pAnchoredObj->ISA(SwFlyFrm) )
2208 : {
2209 703 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2210 703 : pFly->_Invalidate();
2211 703 : pFly->_InvalidatePos();
2212 703 : if ( !_bInvaPosOnly )
2213 0 : pFly->_InvalidateSize();
2214 : }
2215 : else
2216 : {
2217 482 : pAnchoredObj->InvalidateObjPos();
2218 : }
2219 : } // end of loop on objects, which are connected to the frame
2220 : }
2221 31010 : }
2222 :
2223 : // #i26945# - correct check, if anchored object is a lower
2224 : // of the layout frame. E.g., anchor character text frame can be a follow text
2225 : // frame.
2226 : // #i44016# - add parameter <_bUnlockPosOfObjs> to
2227 : // force an unlockposition call for the lower objects.
2228 43662 : void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
2229 : {
2230 : // invalidate lower floating screen objects
2231 43662 : SwPageFrm* pPageFrm = FindPageFrm();
2232 43662 : if ( pPageFrm && pPageFrm->GetSortedObjs() )
2233 : {
2234 6056 : SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
2235 32237 : for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
2236 : {
2237 26181 : SwAnchoredObject* pObj = rObjs[i];
2238 : // #i26945# - check, if anchored object is a lower
2239 : // of the layout frame is changed to check, if its anchor frame
2240 : // is a lower of the layout frame.
2241 : // determine the anchor frame - usually it's the anchor frame,
2242 : // for at-character/as-character anchored objects the anchor character
2243 : // text frame is taken.
2244 26181 : const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
2245 26181 : if ( pObj->ISA(SwFlyFrm) )
2246 : {
2247 16305 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2248 :
2249 16305 : if ( pFly->Frm().Left() == FAR_AWAY )
2250 6637 : continue;
2251 :
2252 9668 : if ( pFly->IsAnLower( this ) )
2253 2578 : continue;
2254 :
2255 : // #i26945# - use <pAnchorFrm> to check, if
2256 : // fly frame is lower of layout frame resp. if fly frame is
2257 : // at a different page registered as its anchor frame is on.
2258 7090 : const bool bLow = IsAnLower( pAnchorFrm );
2259 7090 : if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
2260 : {
2261 358 : pFly->_Invalidate( pPageFrm );
2262 358 : if ( !bLow || pFly->IsFlyAtCntFrm() )
2263 : {
2264 : // #i44016#
2265 358 : if ( _bUnlockPosOfObjs )
2266 : {
2267 186 : pFly->UnlockPosition();
2268 : }
2269 358 : pFly->_InvalidatePos();
2270 : }
2271 : else
2272 0 : pFly->_InvalidatePrt();
2273 : }
2274 : }
2275 : else
2276 : {
2277 : OSL_ENSURE( pObj->ISA(SwAnchoredDrawObject),
2278 : "<SwLayoutFrm::NotifyFlys() - anchored object of unexcepted type" );
2279 : // #i26945# - use <pAnchorFrm> to check, if
2280 : // fly frame is lower of layout frame resp. if fly frame is
2281 : // at a different page registered as its anchor frame is on.
2282 19483 : if ( IsAnLower( pAnchorFrm ) ||
2283 9607 : pAnchorFrm->FindPageFrm() != pPageFrm )
2284 : {
2285 : // #i44016#
2286 269 : if ( _bUnlockPosOfObjs )
2287 : {
2288 92 : pObj->UnlockPosition();
2289 : }
2290 269 : pObj->InvalidateObjPos();
2291 : }
2292 : }
2293 : }
2294 : }
2295 43662 : }
2296 :
2297 3621 : void SwFlyFrm::NotifyDrawObj()
2298 : {
2299 3621 : SwVirtFlyDrawObj* pObj = GetVirtDrawObj();
2300 3621 : pObj->SetRect();
2301 3621 : pObj->SetRectsDirty();
2302 3621 : pObj->SetChanged();
2303 3621 : pObj->BroadcastObjectChange();
2304 3621 : if ( GetFmt()->GetSurround().IsContour() )
2305 0 : ClrContourCache( pObj );
2306 3621 : }
2307 :
2308 7662 : Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
2309 : {
2310 7662 : Size aRet( rSz.GetSize() );
2311 :
2312 7662 : const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
2313 7662 : if( pRel ) // LAYER_IMPL
2314 : {
2315 7662 : long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
2316 7662 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
2317 17818 : if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
2318 13226 : pSh && pSh->GetViewOptions()->getBrowseMode() &&
2319 8 : pSh->VisArea().HasArea() )
2320 : {
2321 8 : nRelWidth = pSh->GetBrowseWidth();
2322 8 : nRelHeight = pSh->VisArea().Height();
2323 8 : Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
2324 8 : long nDiff = nRelWidth - pRel->Prt().Width();
2325 8 : if ( nDiff > 0 )
2326 0 : nRelWidth -= nDiff;
2327 8 : nRelHeight -= 2*aBorder.Height();
2328 8 : nDiff = nRelHeight - pRel->Prt().Height();
2329 8 : if ( nDiff > 0 )
2330 0 : nRelHeight -= nDiff;
2331 : }
2332 :
2333 : // At the moment only the "== PAGE_FRAME" and "!= PAGE_FRAME" cases are handled.
2334 : // When size is a relative to page size, ignore size of SwBodyFrm.
2335 7662 : if (rSz.GetWidthPercentRelation() != text::RelOrientation::PAGE_FRAME)
2336 7552 : nRelWidth = std::min( nRelWidth, pRel->Prt().Width() );
2337 7662 : if (rSz.GetHeightPercentRelation() != text::RelOrientation::PAGE_FRAME)
2338 7564 : nRelHeight = std::min( nRelHeight, pRel->Prt().Height() );
2339 7662 : if( !pRel->IsPageFrm() )
2340 : {
2341 7274 : const SwPageFrm* pPage = FindPageFrm();
2342 7274 : if( pPage )
2343 : {
2344 7274 : if (rSz.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME)
2345 : // Ignore margins of pPage.
2346 110 : nRelWidth = std::min( nRelWidth, pPage->Frm().Width() );
2347 : else
2348 7164 : nRelWidth = std::min( nRelWidth, pPage->Prt().Width() );
2349 7274 : if (rSz.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME)
2350 : // Ignore margins of pPage.
2351 98 : nRelHeight = std::min( nRelHeight, pPage->Frm().Height() );
2352 : else
2353 7176 : nRelHeight = std::min( nRelHeight, pPage->Prt().Height() );
2354 : }
2355 : }
2356 :
2357 7662 : if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
2358 199 : aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
2359 7662 : if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
2360 156 : aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
2361 :
2362 7662 : if ( rSz.GetWidthPercent() == 0xFF )
2363 : {
2364 0 : aRet.Width() *= aRet.Height();
2365 0 : aRet.Width() /= rSz.GetHeight();
2366 : }
2367 7662 : else if ( rSz.GetHeightPercent() == 0xFF )
2368 : {
2369 0 : aRet.Height() *= aRet.Width();
2370 0 : aRet.Height() /= rSz.GetWidth();
2371 : }
2372 : }
2373 7662 : return aRet;
2374 : }
2375 :
2376 390 : static SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
2377 : {
2378 390 : SwTwips nRet = 0;
2379 390 : SwTwips nMin = 0;
2380 390 : const SwFrm* pFrm = rFrm.Lower();
2381 :
2382 : // No autowidth defined for columned frames
2383 390 : if ( !pFrm || pFrm->IsColumnFrm() )
2384 0 : return nRet;
2385 :
2386 1251 : while ( pFrm )
2387 : {
2388 471 : if ( pFrm->IsSctFrm() )
2389 : {
2390 0 : nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
2391 : }
2392 471 : if ( pFrm->IsTxtFrm() )
2393 : {
2394 471 : nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
2395 : const SvxLRSpaceItem &rSpace =
2396 471 : ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
2397 471 : if (!((SwTxtFrm*)pFrm)->IsLocked())
2398 470 : nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst();
2399 : }
2400 0 : else if ( pFrm->IsTabFrm() )
2401 : {
2402 0 : const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize();
2403 0 : if ( USHRT_MAX == rTblFmtSz.GetSize().Width() ||
2404 0 : text::HoriOrientation::NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() )
2405 : {
2406 0 : const SwPageFrm* pPage = rFrm.FindPageFrm();
2407 : // auto width table
2408 0 : nMin = pFrm->GetUpper()->IsVertical() ?
2409 0 : pPage->Prt().Height() :
2410 0 : pPage->Prt().Width();
2411 : }
2412 : else
2413 : {
2414 0 : nMin = rTblFmtSz.GetSize().Width();
2415 : }
2416 : }
2417 :
2418 471 : if ( nMin > nRet )
2419 390 : nRet = nMin;
2420 :
2421 471 : pFrm = pFrm->GetNext();
2422 : }
2423 :
2424 390 : return nRet;
2425 : }
2426 :
2427 390 : SwTwips SwFlyFrm::CalcAutoWidth() const
2428 : {
2429 390 : return lcl_CalcAutoWidth( *this );
2430 : }
2431 :
2432 : /// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTxtFrm> contains
2433 : /// a graphic, load of intrinsic graphic has to be avoided.
2434 129 : sal_Bool SwFlyFrm::GetContour( PolyPolygon& rContour,
2435 : const sal_Bool _bForPaint ) const
2436 : {
2437 129 : sal_Bool bRet = sal_False;
2438 153 : if( GetFmt()->GetSurround().IsContour() && Lower() &&
2439 24 : Lower()->IsNoTxtFrm() )
2440 : {
2441 24 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
2442 : // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
2443 : // in order to avoid load of graphic, if <SwNoTxtNode> contains a graphic
2444 : // node and method is called for paint.
2445 24 : const GraphicObject* pGrfObj = NULL;
2446 24 : bool bGrfObjCreated = false;
2447 24 : const SwGrfNode* pGrfNd = pNd->GetGrfNode();
2448 24 : if ( pGrfNd && _bForPaint )
2449 : {
2450 16 : pGrfObj = &(pGrfNd->GetGrfObj());
2451 : }
2452 : else
2453 : {
2454 8 : pGrfObj = new GraphicObject( pNd->GetGraphic() );
2455 8 : bGrfObjCreated = true;
2456 : }
2457 : OSL_ENSURE( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
2458 24 : if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE )
2459 : {
2460 0 : if( !pNd->HasContour() )
2461 : {
2462 : // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
2463 : // during paint. Thus, return (value of <bRet> should be <sal_False>).
2464 0 : if ( pGrfNd && _bForPaint )
2465 : {
2466 : OSL_FAIL( "SwFlyFrm::GetContour() - No Contour found at <SwNoTxtNode> during paint." );
2467 0 : return bRet;
2468 : }
2469 0 : pNd->CreateContour();
2470 : }
2471 0 : pNd->GetContour( rContour );
2472 : // The Node holds the Polygon matching the original size of the graphic
2473 : // We need to include the scaling here
2474 0 : SwRect aClip;
2475 0 : SwRect aOrig;
2476 0 : Lower()->Calc();
2477 0 : ((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, false );
2478 : // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
2479 : // in order to avoid that graphic has to be loaded for contour scale.
2480 : //SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() );
2481 : {
2482 0 : OutputDevice* pOutDev = Application::GetDefaultDevice();
2483 0 : const MapMode aDispMap( MAP_TWIP );
2484 0 : const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
2485 0 : const Size aGrfSize( pGrfObj->GetPrefSize() );
2486 0 : Size aOrgSize;
2487 0 : Point aNewPoint;
2488 0 : bool bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL;
2489 :
2490 0 : if ( bPixelMap )
2491 0 : aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
2492 : else
2493 0 : aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap );
2494 :
2495 0 : if ( aOrgSize.Width() && aOrgSize.Height() )
2496 : {
2497 0 : double fScaleX = (double) aOrig.Width() / aOrgSize.Width();
2498 0 : double fScaleY = (double) aOrig.Height() / aOrgSize.Height();
2499 :
2500 0 : for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
2501 : {
2502 0 : Polygon& rPoly = rContour[ j ];
2503 :
2504 0 : for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
2505 : {
2506 0 : if ( bPixelMap )
2507 0 : aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
2508 : else
2509 0 : aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
2510 :
2511 0 : rPoly[ i ] = Point( FRound( aNewPoint.getX() * fScaleX ), FRound( aNewPoint.getY() * fScaleY ) );
2512 : }
2513 : }
2514 0 : }
2515 : }
2516 : // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
2517 0 : if ( bGrfObjCreated )
2518 : {
2519 0 : delete pGrfObj;
2520 : }
2521 0 : rContour.Move( aOrig.Left(), aOrig.Top() );
2522 0 : if( !aClip.Width() )
2523 0 : aClip.Width( 1 );
2524 0 : if( !aClip.Height() )
2525 0 : aClip.Height( 1 );
2526 0 : rContour.Clip( aClip.SVRect() );
2527 0 : rContour.Optimize(POLY_OPTIMIZE_CLOSE);
2528 0 : bRet = sal_True;
2529 : }
2530 : }
2531 129 : return bRet;
2532 : }
2533 :
2534 : // OD 2004-03-25 #i26791#
2535 1623 : const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
2536 : {
2537 1623 : return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
2538 : }
2539 52701 : SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
2540 : {
2541 52701 : return static_cast<SwVirtFlyDrawObj*>(DrawObj());
2542 : }
2543 :
2544 : // OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
2545 : // base class <SwAnchoredObject>
2546 :
2547 521 : void SwFlyFrm::InvalidateObjPos()
2548 : {
2549 521 : InvalidatePos();
2550 : // #i68520#
2551 521 : InvalidateObjRectWithSpaces();
2552 521 : }
2553 :
2554 84431 : SwFrmFmt& SwFlyFrm::GetFrmFmt()
2555 : {
2556 : OSL_ENSURE( GetFmt(),
2557 : "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2558 84431 : return *GetFmt();
2559 : }
2560 172394 : const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
2561 : {
2562 : OSL_ENSURE( GetFmt(),
2563 : "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2564 172394 : return *GetFmt();
2565 : }
2566 :
2567 219453 : const SwRect SwFlyFrm::GetObjRect() const
2568 : {
2569 219453 : return Frm();
2570 : }
2571 :
2572 : // #i70122#
2573 : // for Writer fly frames the bounding rectangle equals the object rectangles
2574 5097 : const SwRect SwFlyFrm::GetObjBoundRect() const
2575 : {
2576 5097 : return GetObjRect();
2577 : }
2578 :
2579 : // #i68520#
2580 3981 : bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
2581 : {
2582 3981 : const bool bChanged( Frm().Pos().getY() != _nTop );
2583 :
2584 3981 : Frm().Pos().setY(_nTop);
2585 :
2586 3981 : return bChanged;
2587 : }
2588 1327 : bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
2589 : {
2590 1327 : const bool bChanged( Frm().Pos().getX() != _nLeft );
2591 :
2592 1327 : Frm().Pos().setX(_nLeft);
2593 :
2594 1327 : return bChanged;
2595 : }
2596 :
2597 : /** method to assure that anchored object is registered at the correct
2598 : page frame
2599 :
2600 : OD 2004-07-02 #i28701#
2601 : */
2602 0 : void SwFlyFrm::RegisterAtCorrectPage()
2603 : {
2604 : // default behaviour is to do nothing.
2605 0 : }
2606 :
2607 : /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
2608 :
2609 : OD 2004-05-11 #i28701#
2610 : */
2611 5493 : bool SwFlyFrm::IsFormatPossible() const
2612 : {
2613 10986 : return SwAnchoredObject::IsFormatPossible() &&
2614 10986 : !IsLocked() && !IsColLocked();
2615 : }
2616 :
2617 4 : void SwFlyFrm::GetAnchoredObjects( std::list<SwAnchoredObject*>& aList, const SwFmt& rFmt )
2618 : {
2619 4 : SwIterator<SwFlyFrm,SwFmt> aIter( rFmt );
2620 8 : for( SwFlyFrm* pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
2621 8 : aList.push_back( pFlyFrm );
2622 4 : }
2623 :
2624 216607 : const SwFlyFrmFmt * SwFlyFrm::GetFmt() const
2625 : {
2626 216607 : return static_cast< const SwFlyFrmFmt * >( GetDep() );
2627 : }
2628 :
2629 171723 : SwFlyFrmFmt * SwFlyFrm::GetFmt()
2630 : {
2631 171723 : return static_cast< SwFlyFrmFmt * >( GetDep() );
2632 : }
2633 :
2634 5446 : void SwFlyFrm::Calc() const
2635 : {
2636 5446 : if ( !m_bValidContentPos )
2637 1434 : ((SwFlyFrm*)this)->PrepareMake();
2638 : else
2639 4012 : SwLayoutFrm::Calc();
2640 5446 : }
2641 :
2642 2523 : SwTwips SwFlyFrm::CalcContentHeight(const SwBorderAttrs *pAttrs, const SwTwips nMinHeight, const SwTwips nUL)
2643 : {
2644 2523 : SWRECTFN( this )
2645 2523 : SwTwips nHeight = 0;
2646 2523 : if ( Lower() )
2647 : {
2648 2521 : if ( Lower()->IsColumnFrm() )
2649 : {
2650 0 : FormatWidthCols( *pAttrs, nUL, nMinHeight );
2651 0 : nHeight = (Lower()->Frm().*fnRect->fnGetHeight)();
2652 : }
2653 : else
2654 : {
2655 2521 : SwFrm *pFrm = Lower();
2656 9923 : while ( pFrm )
2657 : {
2658 4881 : nHeight += (pFrm->Frm().*fnRect->fnGetHeight)();
2659 4881 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
2660 : // This TxtFrm would like to be a bit larger
2661 227 : nHeight += ((SwTxtFrm*)pFrm)->GetParHeight()
2662 227 : - (pFrm->Prt().*fnRect->fnGetHeight)();
2663 4654 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
2664 0 : nHeight += ((SwSectionFrm*)pFrm)->Undersize();
2665 4881 : pFrm = pFrm->GetNext();
2666 : }
2667 : }
2668 2521 : if ( GetDrawObjs() )
2669 : {
2670 0 : sal_uInt32 nCnt = GetDrawObjs()->Count();
2671 0 : SwTwips nTop = (Frm().*fnRect->fnGetTop)();
2672 0 : SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
2673 0 : (Prt().*fnRect->fnGetHeight)();
2674 0 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
2675 : {
2676 0 : SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2677 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
2678 : {
2679 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2680 : // OD 06.11.2003 #i22305# - consider
2681 : // only Writer fly frames, which follow the text flow.
2682 0 : if ( pFly->IsFlyLayFrm() &&
2683 0 : pFly->Frm().Top() != FAR_AWAY &&
2684 0 : pFly->GetFmt()->GetFollowTextFlow().GetValue() )
2685 : {
2686 0 : SwTwips nDist = -(pFly->Frm().*fnRect->
2687 0 : fnBottomDist)( nTop );
2688 0 : if( nDist > nBorder + nHeight )
2689 0 : nHeight = nDist - nBorder;
2690 : }
2691 : }
2692 : }
2693 : }
2694 : }
2695 2523 : return nHeight;
2696 : }
2697 :
2698 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|