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 0 : TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
64 :
65 0 : 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 0 : m_bValidContentPos( false )
77 : {
78 0 : mnType = FRMC_FLY;
79 :
80 0 : bInvalid = bNotifyBack = sal_True;
81 : bLocked = bMinHeight =
82 0 : bHeightClipped = bWidthClipped = bFormatHeightOnly = sal_False;
83 :
84 : // Size setting: Fixed size is always the width
85 0 : const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
86 : sal_uInt16 nDir =
87 0 : ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue();
88 0 : if( FRMDIR_ENVIRONMENT == nDir )
89 : {
90 0 : mbDerivedVert = 1;
91 0 : mbDerivedR2L = 1;
92 : }
93 : else
94 : {
95 0 : mbInvalidVert = 0;
96 0 : mbDerivedVert = 0;
97 0 : mbDerivedR2L = 0;
98 0 : 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 0 : mbVertLR = 0;
102 0 : 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 0 : mbInvalidR2L = 0;
125 0 : if( FRMDIR_HORI_RIGHT_TOP == nDir )
126 0 : mbRightToLeft = 1;
127 : else
128 0 : mbRightToLeft = 0;
129 : }
130 :
131 0 : Frm().Width( rFrmSize.GetWidth() );
132 0 : Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
133 :
134 : // Fixed or variable Height?
135 0 : if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
136 0 : bMinHeight = sal_True;
137 0 : else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
138 0 : mbFixSize = sal_True;
139 :
140 : // insert columns, if necessary
141 0 : 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 0 : InitDrawObj( sal_False );
147 :
148 0 : Chain( pAnch );
149 :
150 0 : InsertCnt();
151 :
152 : // Put it somewhere outside so that out document is not formatted unnecessarily often
153 0 : Frm().Pos().setX(FAR_AWAY);
154 0 : Frm().Pos().setY(FAR_AWAY);
155 0 : }
156 :
157 0 : 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 0 : const SwFmtChain& rChain = GetFmt()->GetChain();
163 0 : if ( rChain.GetPrev() || rChain.GetNext() )
164 : {
165 0 : if ( rChain.GetNext() )
166 : {
167 0 : SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
168 0 : 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 0 : if ( rChain.GetPrev() )
176 : {
177 0 : SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
178 0 : if ( pMaster )
179 : {
180 : OSL_ENSURE( !pMaster->GetNextLink(), "wrong chain detected" );
181 0 : if ( !pMaster->GetNextLink() )
182 0 : SwFlyFrm::ChainFrames( pMaster, this );
183 : }
184 : }
185 : }
186 0 : }
187 :
188 0 : void SwFlyFrm::InsertCnt()
189 : {
190 0 : if ( !GetPrevLink() )
191 : {
192 0 : const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
193 : OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( no content prepared." );
194 0 : sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
195 : // Lower() means SwColumnFrm; the Content then needs to be instered into the (Column)BodyFrm
196 0 : ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
197 0 : GetFmt()->GetDoc(), nIndex );
198 :
199 : // NoTxt always have a fixed height.
200 0 : if ( Lower() && Lower()->IsNoTxtFrm() )
201 : {
202 0 : mbFixSize = sal_True;
203 0 : bMinHeight = sal_False;
204 : }
205 : }
206 0 : }
207 :
208 0 : 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 0 : const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
214 : OSL_ENSURE( rCntnt.GetCntntIdx(), "<SwFlyFrm::InsertColumns()> - no content prepared." );
215 0 : SwNodeIndex aFirstCntnt( *(rCntnt.GetCntntIdx()), 1 );
216 0 : if ( aFirstCntnt.GetNode().IsNoTxtNode() )
217 : {
218 0 : return;
219 : }
220 :
221 0 : const SwFmtCol &rCol = GetFmt()->GetCol();
222 0 : 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 0 : }
231 : }
232 :
233 0 : 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 0 : if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
240 : {
241 0 : SwRootFrm *pRootFrm = getRootFrm();
242 0 : 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 0 : if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
255 : {
256 : // OD 2004-01-19 #110582#
257 0 : Unchain();
258 :
259 : // OD 2004-01-19 #110582#
260 0 : DeleteCnt();
261 :
262 0 : if ( GetAnchorFrm() )
263 0 : AnchorFrm()->RemoveFly( this );
264 : }
265 :
266 0 : FinitDrawObj();
267 0 : }
268 :
269 0 : const IDocumentDrawModelAccess* SwFlyFrm::getIDocumentDrawModelAccess()
270 : {
271 0 : return GetFmt()->getIDocumentDrawModelAccess();
272 : }
273 :
274 : // OD 2004-01-19 #110582#
275 0 : void SwFlyFrm::Unchain()
276 : {
277 0 : if ( GetPrevLink() )
278 0 : UnchainFrames( GetPrevLink(), this );
279 0 : if ( GetNextLink() )
280 0 : UnchainFrames( this, GetNextLink() );
281 0 : }
282 :
283 : // OD 2004-01-19 #110582#
284 0 : void SwFlyFrm::DeleteCnt()
285 : {
286 : // #110582#-2
287 0 : if ( IsLockDeleteContent() )
288 0 : return;
289 :
290 0 : SwFrm* pFrm = pLower;
291 0 : while ( pFrm )
292 : {
293 0 : while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
294 : {
295 0 : SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
296 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
297 0 : delete pAnchoredObj;
298 0 : else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
299 : {
300 : // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
301 0 : SdrObject* pObj = pAnchoredObj->DrawObj();
302 0 : 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 0 : static_cast<SwDrawContact*>(::GetUserCall( pObj ));
312 0 : if ( pContact )
313 : {
314 0 : pContact->DisconnectFromLayout();
315 : }
316 : }
317 : }
318 : }
319 :
320 0 : pFrm->Remove();
321 0 : delete pFrm;
322 0 : pFrm = pLower;
323 : }
324 :
325 0 : InvalidatePage();
326 : }
327 :
328 0 : sal_uInt32 SwFlyFrm::_GetOrdNumForNewRef( const SwFlyDrawContact* pContact )
329 : {
330 0 : sal_uInt32 nOrdNum( 0L );
331 :
332 : // search for another Writer fly frame registered at same frame format
333 0 : SwIterator<SwFlyFrm,SwFmt> aIter( *pContact->GetFmt() );
334 0 : const SwFlyFrm* pFlyFrm( 0L );
335 0 : for ( pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
336 : {
337 0 : if ( pFlyFrm != this )
338 : {
339 0 : break;
340 : }
341 : }
342 :
343 0 : if ( pFlyFrm )
344 : {
345 : // another Writer fly frame found. Take its order number
346 0 : 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 0 : nOrdNum = pContact->GetMaster()->GetOrdNumDirect();
355 : }
356 :
357 0 : return nOrdNum;
358 : }
359 :
360 0 : SwVirtFlyDrawObj* SwFlyFrm::CreateNewRef( SwFlyDrawContact *pContact )
361 : {
362 0 : SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *pContact->GetMaster(), this );
363 0 : pDrawObj->SetModel( pContact->GetMaster()->GetModel() );
364 0 : 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 0 : SdrPage* pPg( 0L );
371 0 : if ( 0 != ( pPg = pContact->GetMaster()->GetPage() ) )
372 : {
373 0 : const sal_uInt32 nOrdNum = pContact->GetMaster()->GetOrdNum();
374 0 : pPg->ReplaceObject( pDrawObj, nOrdNum );
375 : }
376 : // #i27030# - insert new <SwVirtFlyDrawObj> instance
377 : // into drawing page with correct order number
378 : else
379 : {
380 0 : pContact->GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
381 0 : InsertObject( pDrawObj, _GetOrdNumForNewRef( pContact ) );
382 : }
383 : // #i38889# - assure, that new <SwVirtFlyDrawObj> instance
384 : // is in a visible layer.
385 0 : pContact->MoveObjToVisibleLayer( pDrawObj );
386 0 : return pDrawObj;
387 : }
388 :
389 0 : 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 0 : IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
395 0 : SwFlyDrawContact *pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
396 0 : if ( !pContact )
397 : {
398 : // #i52858# - method name changed
399 0 : pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
400 0 : pIDDMA->GetOrCreateDrawModel() );
401 : }
402 : OSL_ENSURE( pContact, "InitDrawObj failed" );
403 : // OD 2004-03-22 #i26791#
404 0 : SetDrawObj( *(CreateNewRef( pContact )) );
405 :
406 : // Set the right Layer
407 : // OD 2004-01-19 #110582#
408 0 : SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
409 0 : SdrLayerID nHellId = pIDDMA->GetHellId();
410 : // OD 2004-03-22 #i26791#
411 0 : GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
412 : ? nHeavenId
413 0 : : nHellId );
414 0 : if ( bNotify )
415 0 : NotifyDrawObj();
416 0 : }
417 :
418 0 : void SwFlyFrm::FinitDrawObj()
419 : {
420 0 : if ( !GetVirtDrawObj() )
421 0 : return;
422 :
423 : // Deregister from SdrPageViews if the Objects is still selected there.
424 0 : if ( !GetFmt()->GetDoc()->IsInDtor() )
425 : {
426 0 : SwViewShell *p1St = getRootFrm()->GetCurrShell();
427 0 : if ( p1St )
428 : {
429 0 : SwViewShell *pSh = p1St;
430 0 : do
431 : { // At the moment the Drawing can do just do an Unmark on everything,
432 : // as the Object was already removed
433 0 : if( pSh->HasDrawView() )
434 0 : pSh->Imp()->GetDrawView()->UnmarkAll();
435 0 : 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 0 : SwFlyDrawContact *pMyContact = 0;
445 0 : if ( GetFmt() )
446 : {
447 0 : bool bContinue = true;
448 0 : SwIterator<SwFrm,SwFmt> aFrmIter( *GetFmt() );
449 0 : for ( SwFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
450 0 : if ( pFrm != this )
451 : {
452 : // don't delete Contact if there is still a Frm
453 0 : bContinue = false;
454 0 : break;
455 : }
456 :
457 0 : if ( bContinue )
458 : // no Frm left, find Contact object to destroy
459 0 : 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 0 : if ( pMyContact )
466 : {
467 0 : pMyContact->GetMaster()->SetUserCall( 0 );
468 : }
469 0 : GetVirtDrawObj()->SetUserCall( 0 ); // Else calls delete of the ContactObj
470 0 : delete GetVirtDrawObj(); // Deregisters itself at the Master
471 0 : delete pMyContact; // Destroys the Master itself
472 : }
473 :
474 0 : 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 0 : pMaster->pNextLink = pFollow;
481 0 : pFollow->pPrevLink = pMaster;
482 :
483 0 : if ( pMaster->ContainsCntnt() )
484 : {
485 : // To get a text flow we need to invalidate
486 0 : SwFrm *pInva = pMaster->FindLastLower();
487 0 : SWRECTFN( pMaster )
488 0 : const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
489 0 : while ( pInva )
490 : {
491 0 : 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 0 : pInva = 0;
499 : }
500 : }
501 :
502 0 : 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 0 : SwViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
514 0 : if( pSh )
515 : {
516 0 : SwRootFrm* pLayout = pMaster->getRootFrm();
517 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
518 0 : pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
519 : }
520 0 : }
521 :
522 0 : void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
523 : {
524 0 : pMaster->pNextLink = 0;
525 0 : pFollow->pPrevLink = 0;
526 :
527 0 : 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 0 : const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
551 : OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( No content prepared." );
552 0 : sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
553 : // Lower() means SwColumnFrm: this one contains another SwBodyFrm
554 0 : ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
555 : : (SwLayoutFrm*)pFollow,
556 0 : pFollow->GetFmt()->GetDoc(), ++nIndex );
557 :
558 : // invalidate accessible relation set (accessibility wrapper)
559 0 : SwViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
560 0 : if( pSh )
561 : {
562 0 : SwRootFrm* pLayout = pMaster->getRootFrm();
563 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
564 0 : pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
565 : }
566 0 : }
567 :
568 0 : 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 0 : if ( !pAnch ) // If an Anchor was passed along, that one counts (ctor!)
574 0 : pAnch = AnchorFrm();
575 :
576 : SwLayoutFrm *pLay;
577 0 : 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 0 : pLay = pAnch->GetUpper();
584 0 : while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
585 0 : pLay = pLay->GetUpper();
586 : }
587 :
588 0 : SwIterator<SwFlyFrm,SwFmt> aIter( rChain );
589 0 : SwFlyFrm *pFly = aIter.First();
590 0 : 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 0 : return pFly;
612 : }
613 :
614 0 : SwFrm *SwFlyFrm::FindLastLower()
615 : {
616 0 : SwFrm *pRet = ContainsAny();
617 0 : if ( pRet && pRet->IsInTab() )
618 0 : pRet = pRet->FindTabFrm();
619 0 : SwFrm *pNxt = pRet;
620 0 : while ( pNxt && IsAnLower( pNxt ) )
621 0 : { pRet = pNxt;
622 0 : pNxt = pNxt->FindNext();
623 : }
624 0 : return pRet;
625 : }
626 :
627 0 : sal_Bool SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
628 : {
629 0 : sal_Bool bRet = sal_False;
630 0 : SwTwips nDiffHeight = Frm().Height();
631 0 : if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
632 0 : mbFixSize = bMinHeight = sal_False;
633 : else
634 : {
635 0 : if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
636 : {
637 0 : mbFixSize = sal_True;
638 0 : bMinHeight = sal_False;
639 : }
640 0 : else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
641 : {
642 0 : mbFixSize = sal_False;
643 0 : bMinHeight = sal_True;
644 : }
645 0 : 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 0 : if ( Lower() )
650 : {
651 0 : 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 0 : else if ( Lower()->IsNoTxtFrm() )
668 : {
669 0 : mbFixSize = sal_True;
670 0 : bMinHeight = sal_False;
671 : }
672 : }
673 0 : return bRet;
674 : }
675 :
676 0 : void SwFlyFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
677 : {
678 0 : sal_uInt8 nInvFlags = 0;
679 :
680 0 : if (pNew && pOld && RES_ATTRSET_CHG == pNew->Which())
681 : {
682 0 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
683 0 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
684 0 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
685 0 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
686 : while( true )
687 : {
688 : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
689 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
690 0 : &aOldSet, &aNewSet );
691 0 : if( aNIter.IsAtEnd() )
692 0 : break;
693 0 : aNIter.NextItem();
694 0 : aOIter.NextItem();
695 : }
696 0 : if ( aOldSet.Count() || aNewSet.Count() )
697 0 : SwLayoutFrm::Modify( &aOldSet, &aNewSet );
698 : }
699 : else
700 0 : _UpdateAttr( pOld, pNew, nInvFlags );
701 :
702 0 : if ( nInvFlags != 0 )
703 : {
704 0 : _Invalidate();
705 0 : if ( nInvFlags & 0x01 )
706 : {
707 0 : _InvalidatePos();
708 : // #i68520#
709 0 : InvalidateObjRectWithSpaces();
710 : }
711 0 : if ( nInvFlags & 0x02 )
712 : {
713 0 : _InvalidateSize();
714 : // #i68520#
715 0 : InvalidateObjRectWithSpaces();
716 : }
717 0 : if ( nInvFlags & 0x04 )
718 0 : _InvalidatePrt();
719 0 : if ( nInvFlags & 0x08 )
720 0 : SetNotifyBack();
721 0 : if ( nInvFlags & 0x10 )
722 0 : SetCompletePaint();
723 0 : if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
724 0 : ClrContourCache( GetVirtDrawObj() );
725 : SwRootFrm *pRoot;
726 0 : if ( nInvFlags & 0x20 && 0 != (pRoot = getRootFrm()) )
727 0 : pRoot->InvalidateBrowseWidth();
728 : // #i28701#
729 0 : if ( nInvFlags & 0x80 )
730 : {
731 : // update sorted object lists, the Writer fly frame is registered at.
732 0 : UpdateObjInSortedList();
733 : }
734 :
735 : // #i87645# - reset flags for the layout process (only if something has been invalidated)
736 0 : ResetLayoutProcessBools();
737 : }
738 0 : }
739 :
740 0 : void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
741 : sal_uInt8 &rInvFlags,
742 : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
743 : {
744 0 : bool bClear = true;
745 0 : const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
746 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
747 0 : 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 0 : rInvFlags |= 0x09;
756 : }
757 0 : 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 0 : rInvFlags |= 0x41;
770 : // The background needs to messaged and invalidated
771 0 : const SwRect aTmp( GetObjRectWithSpaces() );
772 0 : 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 0 : if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
777 0 : rInvFlags |= 0x09;
778 :
779 : // Delete contour in the Node if necessary
780 0 : if ( Lower() && Lower()->IsNoTxtFrm() &&
781 0 : !GetFmt()->GetSurround().IsContour() )
782 : {
783 0 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
784 0 : 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 0 : rInvFlags |= 0x80;
790 : }
791 0 : break;
792 :
793 : case RES_PROTECT:
794 0 : if (pNew)
795 : {
796 0 : const SvxProtectItem *pP = (SvxProtectItem*)pNew;
797 0 : GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() );
798 0 : GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
799 0 : if( pSh )
800 : {
801 0 : SwRootFrm* pLayout = getRootFrm();
802 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
803 0 : pSh->Imp()->InvalidateAccessibleEditableState( true, this );
804 : }
805 : }
806 0 : 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 0 : const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
822 0 : if ( FrmSizeChg( rNew ) )
823 0 : NotifyDrawObj();
824 0 : rInvFlags |= 0x7F;
825 0 : if ( RES_FMT_CHG == nWhich )
826 : {
827 0 : SwRect aNew( GetObjRectWithSpaces() );
828 0 : SwRect aOld( maFrm );
829 0 : const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
830 0 : aOld.Top( std::max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
831 0 : aOld.SSize().Height()+= rUL.GetLower();
832 0 : const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
833 0 : aOld.Left ( std::max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
834 0 : aOld.SSize().Width() += rLR.GetRight();
835 0 : aNew.Union( aOld );
836 0 : 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 0 : SwFmtCol aCol;
843 0 : 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 0 : ChgColumns( aCol, GetFmt()->GetCol() );
854 : }
855 :
856 0 : SwFmtURL aURL( GetFmt()->GetURL() );
857 0 : if ( aURL.GetMap() )
858 : {
859 : const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
860 : *(SwFmtFrmSize*)pNew :
861 0 : ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
862 : //#35091# Can be "times zero", when loading the template
863 0 : if ( rOld.GetWidth() && rOld.GetHeight() )
864 : {
865 :
866 0 : Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
867 0 : Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
868 0 : aURL.GetMap()->Scale( aScaleX, aScaleY );
869 0 : SwFrmFmt *pFmt = GetFmt();
870 0 : pFmt->LockModify();
871 0 : pFmt->SetFmtAttr( aURL );
872 0 : pFmt->UnlockModify();
873 : }
874 : }
875 0 : const SvxProtectItem &rP = GetFmt()->GetProtect();
876 0 : GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() );
877 0 : GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
878 :
879 0 : if ( pSh )
880 0 : pSh->InvalidateWindows( Frm() );
881 0 : const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
882 0 : const sal_uInt8 nId = GetFmt()->GetOpaque().GetValue() ?
883 0 : pIDDMA->GetHeavenId() :
884 0 : pIDDMA->GetHellId();
885 0 : GetVirtDrawObj()->SetLayer( nId );
886 :
887 0 : if ( Lower() )
888 : {
889 : // Delete contour in the Node if necessary
890 0 : if( Lower()->IsNoTxtFrm() &&
891 0 : !GetFmt()->GetSurround().IsContour() )
892 : {
893 0 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
894 0 : if ( pNd->HasContour() )
895 0 : pNd->SetContour( 0 );
896 : }
897 0 : else if( !Lower()->IsColumnFrm() )
898 : {
899 0 : SwFrm* pFrm = GetLastLower();
900 0 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
901 0 : pFrm->Prepare( PREP_ADJUST_FRM );
902 : }
903 : }
904 :
905 : // #i28701# - perform reorder of object lists
906 : // at anchor frame and at page frame.
907 0 : rInvFlags |= 0x80;
908 :
909 0 : 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 0 : SetDerivedVert( sal_False );
950 0 : SetDerivedR2L( sal_False );
951 0 : CheckDirChange();
952 0 : 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 0 : if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
983 0 : ((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 0 : 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 0 : bClear = false;
1043 : }
1044 0 : if ( bClear )
1045 : {
1046 0 : if ( pOldSet || pNewSet )
1047 : {
1048 0 : if ( pOldSet )
1049 0 : pOldSet->ClearItem( nWhich );
1050 0 : if ( pNewSet )
1051 0 : pNewSet->ClearItem( nWhich );
1052 : }
1053 : else
1054 0 : SwLayoutFrm::Modify( pOld, pNew );
1055 : }
1056 0 : }
1057 :
1058 : /// Gets information from the Modify
1059 0 : bool SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
1060 : {
1061 0 : if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
1062 0 : return false; // There's a FlyFrm, so use it
1063 0 : return true; // Continue searching
1064 : }
1065 :
1066 0 : void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
1067 : {
1068 0 : InvalidatePage( pPage );
1069 0 : bNotifyBack = bInvalid = sal_True;
1070 :
1071 : SwFlyFrm *pFrm;
1072 0 : 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 0 : if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
1077 0 : 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 0 : if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() )
1086 : {
1087 0 : const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() );
1088 0 : if ( pSectFrm && pSectFrm->GetSection() == 0 )
1089 : {
1090 0 : InvalidatePos();
1091 0 : ClearVertPosOrientFrm();
1092 : }
1093 : }
1094 0 : }
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 0 : void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
1219 : {
1220 : OSL_ENSURE( pAttrs, "FlyFrm::Format, pAttrs is 0." );
1221 :
1222 0 : ColLock();
1223 :
1224 0 : if ( !mbValidSize )
1225 : {
1226 0 : if ( Frm().Top() == FAR_AWAY && Frm().Left() == FAR_AWAY )
1227 : {
1228 : // Remove safety switch (see SwFrm::CTor)
1229 0 : Frm().Pos().setX(0);
1230 0 : Frm().Pos().setY(0);
1231 : // #i68520#
1232 0 : InvalidateObjRectWithSpaces();
1233 : }
1234 :
1235 : // Check column width and set it if needed
1236 0 : if ( Lower() && Lower()->IsColumnFrm() )
1237 0 : AdjustColumns( 0, sal_False );
1238 :
1239 0 : mbValidSize = sal_True;
1240 :
1241 0 : const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
1242 0 : const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
1243 0 : const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
1244 0 : 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 0 : SWRECTFN( this )
1250 0 : if( !HasFixSize() )
1251 : {
1252 0 : long nMinHeight = 0;
1253 0 : if( IsMinHeight() )
1254 0 : nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1255 :
1256 0 : SwTwips nRemaining = CalcContentHeight(pAttrs, nMinHeight, nUL);
1257 0 : if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
1258 0 : 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 0 : if ( nRemaining < MINFLY )
1267 0 : nRemaining = MINFLY;
1268 :
1269 0 : (Prt().*fnRect->fnSetHeight)( nRemaining );
1270 0 : nRemaining -= (Frm().*fnRect->fnGetHeight)();
1271 0 : (Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
1272 : // #i68520#
1273 0 : if ( nRemaining + nUL != 0 )
1274 : {
1275 0 : InvalidateObjRectWithSpaces();
1276 : }
1277 0 : mbValidSize = sal_True;
1278 : }
1279 : else
1280 : {
1281 0 : mbValidSize = sal_True; // Fixed Frms do not Format itself
1282 : // Flys set their size using the attr
1283 0 : SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
1284 0 : nNewSize -= nUL;
1285 0 : if( nNewSize < MINFLY )
1286 0 : nNewSize = MINFLY;
1287 0 : (Prt().*fnRect->fnSetHeight)( nNewSize );
1288 0 : nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
1289 0 : (Frm().*fnRect->fnAddBottom)( nNewSize );
1290 : // #i68520#
1291 0 : if ( nNewSize != 0 )
1292 : {
1293 0 : InvalidateObjRectWithSpaces();
1294 : }
1295 : }
1296 :
1297 0 : if ( !bFormatHeightOnly )
1298 : {
1299 : OSL_ENSURE( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" );
1300 0 : SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
1301 :
1302 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1303 : {
1304 : // #i9046# Autowidth for fly frames
1305 0 : const SwTwips nAutoWidth = CalcAutoWidth();
1306 0 : if ( nAutoWidth )
1307 : {
1308 0 : if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
1309 0 : nNewSize = std::max( nNewSize - nLR, nAutoWidth );
1310 : else
1311 0 : nNewSize = nAutoWidth;
1312 : }
1313 : }
1314 : else
1315 0 : nNewSize -= nLR;
1316 :
1317 0 : if( nNewSize < MINFLY )
1318 0 : nNewSize = MINFLY;
1319 0 : (Prt().*fnRect->fnSetWidth)( nNewSize );
1320 0 : nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
1321 0 : (Frm().*fnRect->fnAddRight)( nNewSize );
1322 : // #i68520#
1323 0 : if ( nNewSize != 0 )
1324 : {
1325 0 : InvalidateObjRectWithSpaces();
1326 : }
1327 : }
1328 : }
1329 0 : ColUnlock();
1330 0 : }
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 0 : void CalcCntnt( SwLayoutFrm *pLay,
1343 : bool bNoColl,
1344 : bool bNoCalcFollow )
1345 : {
1346 : SwSectionFrm* pSect;
1347 0 : bool bCollect = false;
1348 0 : if( pLay->IsSctFrm() )
1349 : {
1350 0 : pSect = (SwSectionFrm*)pLay;
1351 0 : if( pSect->IsEndnAtEnd() && !bNoColl )
1352 : {
1353 0 : bCollect = true;
1354 0 : SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
1355 : }
1356 0 : pSect->CalcFtnCntnt();
1357 : }
1358 : else
1359 0 : pSect = NULL;
1360 0 : SwFrm *pFrm = pLay->ContainsAny();
1361 0 : if ( !pFrm )
1362 : {
1363 0 : if( pSect )
1364 : {
1365 0 : if( pSect->HasFollow() )
1366 0 : pFrm = pSect->GetFollow()->ContainsAny();
1367 0 : if( !pFrm )
1368 : {
1369 0 : 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 0 : return;
1381 : }
1382 0 : pFrm->_InvalidatePos();
1383 : }
1384 : else
1385 0 : return;
1386 : }
1387 0 : pFrm->InvalidatePage();
1388 :
1389 : do
1390 : {
1391 : // local variables to avoid loops caused by anchored object positioning
1392 0 : SwAnchoredObject* pAgainObj1 = 0;
1393 0 : SwAnchoredObject* pAgainObj2 = 0;
1394 :
1395 : // FME 2007-08-30 #i81146# new loop control
1396 0 : sal_uInt16 nLoopControlRuns = 0;
1397 0 : const sal_uInt16 nLoopControlMax = 20;
1398 0 : const SwFrm* pLoopControlCond = 0;
1399 :
1400 : SwFrm* pLast;
1401 0 : do
1402 : {
1403 0 : pLast = pFrm;
1404 0 : if( pFrm->IsVertical() ?
1405 0 : ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
1406 0 : : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
1407 : {
1408 0 : pFrm->Prepare( PREP_FIXSIZE_CHG );
1409 0 : pFrm->_InvalidateSize();
1410 : }
1411 :
1412 0 : if ( pFrm->IsTabFrm() )
1413 : {
1414 0 : ((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 0 : 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 0 : if ( bNoCalcFollow && pFrm->IsTxtFrm() )
1427 0 : static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
1428 :
1429 0 : pFrm->Calc();
1430 :
1431 : // OD 14.03.2003 #i11760# - reset control flag for follow format.
1432 0 : if ( pFrm->IsTxtFrm() )
1433 : {
1434 0 : 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 0 : SwFrm* pTmpPrev = pFrm->FindPrev();
1446 0 : SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
1447 0 : SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
1448 :
1449 0 : bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
1450 0 : !pTmpFlowFrm->IsFollow() &&
1451 0 : !StackHack::IsLocked() && // #i76382#
1452 0 : !pTmpFlowFrm->IsJoinLocked() &&
1453 0 : !pTmpPrev->GetValidPosFlag() &&
1454 0 : pLay->IsAnLower( pTmpPrev ) &&
1455 0 : pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
1456 0 : pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
1457 :
1458 : // format floating screen objects anchored to the frame.
1459 0 : bool bRestartLayoutProcess = false;
1460 0 : if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
1461 : {
1462 0 : bool bAgain = false;
1463 0 : SwPageFrm* pPageFrm = pFrm->FindPageFrm();
1464 0 : sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
1465 0 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
1466 : {
1467 : // #i28701#
1468 0 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
1469 : // determine, if anchored object has to be formatted.
1470 0 : if ( pAnchoredObj->PositionLocked() )
1471 : {
1472 0 : continue;
1473 : }
1474 :
1475 : // format anchored object
1476 0 : 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 0 : SwRect aRect( pAnchoredObj->GetObjRect() );
1483 0 : 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 0 : if ( pAnchoredObj->PositionLocked() )
1491 : {
1492 0 : bRestartLayoutProcess = true;
1493 0 : break;
1494 : }
1495 :
1496 0 : 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 0 : if ( !pFrm->GetDrawObjs() )
1534 0 : break;
1535 0 : 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 0 : 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 0 : if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1556 : {
1557 0 : pFrm->Calc();
1558 : }
1559 :
1560 0 : 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 0 : if ( pFrm->IsTabFrm() )
1587 : {
1588 0 : if ( ((SwTabFrm*)pFrm)->IsFollow() )
1589 0 : ((SwTabFrm*)pFrm)->bLockBackMove = sal_False;
1590 : }
1591 :
1592 0 : pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
1593 0 : if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
1594 : {
1595 : // Empty SectionFrms could be present here
1596 0 : while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
1597 0 : 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 0 : if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
1602 0 : ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
1603 : {
1604 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1605 0 : if( pFrm )
1606 0 : 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 0 : } while ( pFrm &&
1614 0 : ( pLay->IsAnLower( pFrm ) ||
1615 0 : ( pSect &&
1616 0 : ( ( pSect->HasFollow() &&
1617 0 : ( pLay->IsAnLower( pLast ) ||
1618 0 : ( pLast->IsInSct() &&
1619 0 : pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
1620 0 : pSect->GetFollow()->IsAnLower( pFrm ) ) ||
1621 0 : ( pFrm->IsInSct() &&
1622 0 : pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
1623 0 : if( pSect )
1624 : {
1625 0 : if( bCollect )
1626 : {
1627 0 : pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
1628 0 : pSect->CalcFtnCntnt();
1629 : }
1630 0 : if( pSect->HasFollow() )
1631 : {
1632 0 : SwSectionFrm* pNxt = pSect->GetFollow();
1633 0 : while( pNxt && !pNxt->ContainsCntnt() )
1634 0 : pNxt = pNxt->GetFollow();
1635 0 : if( pNxt )
1636 0 : pNxt->CalcFtnCntnt();
1637 : }
1638 0 : if( bCollect )
1639 : {
1640 0 : pFrm = pLay->ContainsAny();
1641 0 : bCollect = false;
1642 0 : if( pFrm )
1643 0 : continue;
1644 : }
1645 : }
1646 0 : break;
1647 : }
1648 0 : while( true );
1649 : }
1650 :
1651 : // OD 2004-03-23 #i26791#
1652 0 : void SwFlyFrm::MakeObjPos()
1653 : {
1654 0 : if ( !mbValidPos )
1655 : {
1656 0 : mbValidPos = sal_True;
1657 :
1658 : // OD 29.10.2003 #113049# - use new class to position object
1659 0 : GetAnchorFrm()->Calc();
1660 : objectpositioning::SwToLayoutAnchoredObjectPosition
1661 0 : aObjPositioning( *GetVirtDrawObj() );
1662 0 : aObjPositioning.CalcPosition();
1663 :
1664 : // #i58280#
1665 : // update relative position
1666 0 : SetCurrRelPos( aObjPositioning.GetRelPos() );
1667 :
1668 0 : SWRECTFN( GetAnchorFrm() );
1669 0 : maFrm.Pos( aObjPositioning.GetRelPos() );
1670 0 : maFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
1671 : // #i69335#
1672 0 : InvalidateObjRectWithSpaces();
1673 : }
1674 0 : }
1675 :
1676 0 : void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
1677 : {
1678 0 : if ( !mbValidPrtArea )
1679 : {
1680 0 : mbValidPrtArea = sal_True;
1681 :
1682 : // OD 31.07.2003 #110978# - consider vertical layout
1683 0 : SWRECTFN( this )
1684 0 : (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
1685 0 : rAttrs.CalcRightLine() );
1686 0 : (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
1687 0 : rAttrs.CalcBottomLine() );
1688 : }
1689 0 : }
1690 :
1691 0 : void SwFlyFrm::MakeContentPos( const SwBorderAttrs &rAttrs )
1692 : {
1693 0 : if ( !m_bValidContentPos )
1694 : {
1695 0 : m_bValidContentPos = true;
1696 :
1697 0 : const SwTwips nUL = rAttrs.CalcTopLine() + rAttrs.CalcBottomLine();
1698 0 : Size aRelSize( CalcRel( GetFmt()->GetFrmSize() ) );
1699 :
1700 0 : SWRECTFN( this )
1701 0 : long nMinHeight = 0;
1702 0 : if( IsMinHeight() )
1703 0 : nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1704 :
1705 0 : Point aNewContentPos;
1706 0 : aNewContentPos = Prt().Pos();
1707 0 : const SdrTextVertAdjust nAdjust = GetFmt()->GetTextVertAdjust().GetValue();
1708 0 : if( nAdjust != SDRTEXTVERTADJUST_TOP )
1709 : {
1710 0 : SwTwips nDiff = (Prt().*fnRect->fnGetHeight)() - CalcContentHeight(&rAttrs, nMinHeight, nUL);
1711 0 : if( nDiff > 0 )
1712 : {
1713 0 : if( nAdjust == SDRTEXTVERTADJUST_CENTER )
1714 : {
1715 0 : if( bVertL2R )
1716 0 : aNewContentPos.setX(aNewContentPos.getX() + nDiff/2);
1717 0 : else if( bVert )
1718 0 : aNewContentPos.setX(aNewContentPos.getX() - nDiff/2);
1719 : else
1720 0 : aNewContentPos.setY(aNewContentPos.getY() + nDiff/2);
1721 : }
1722 0 : else if( nAdjust == SDRTEXTVERTADJUST_BOTTOM )
1723 : {
1724 0 : if( bVertL2R )
1725 0 : aNewContentPos.setX(aNewContentPos.getX() + nDiff);
1726 0 : else if( bVert )
1727 0 : aNewContentPos.setX(aNewContentPos.getX() - nDiff);
1728 : else
1729 0 : aNewContentPos.setY(aNewContentPos.getY() + nDiff);
1730 : }
1731 : }
1732 : }
1733 0 : if( aNewContentPos != ContentPos() )
1734 : {
1735 0 : ContentPos() = aNewContentPos;
1736 0 : for( SwFrm *pFrm = Lower(); pFrm; pFrm = pFrm->GetNext())
1737 : {
1738 0 : pFrm->InvalidatePos();
1739 : }
1740 : }
1741 : }
1742 0 : }
1743 :
1744 0 : void SwFlyFrm::InvalidateContentPos()
1745 : {
1746 0 : m_bValidContentPos = false;
1747 0 : _Invalidate();
1748 0 : }
1749 :
1750 0 : SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst )
1751 : {
1752 0 : SWRECTFN( this )
1753 0 : if ( Lower() && !IsColLocked() && !HasFixSize() )
1754 : {
1755 0 : SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
1756 0 : if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
1757 0 : nDist = LONG_MAX - nSize;
1758 :
1759 0 : if ( nDist <= 0L )
1760 0 : return 0L;
1761 :
1762 0 : 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 0 : if ( !bTst )
1776 : {
1777 0 : const SwRect aOld( GetObjRectWithSpaces() );
1778 0 : _InvalidateSize();
1779 0 : const sal_Bool bOldLock = bLocked;
1780 0 : Unlock();
1781 0 : 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 0 : 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 0 : const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
1795 0 : const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
1796 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1797 : {
1798 0 : bFormatHeightOnly = sal_True;
1799 : }
1800 0 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
1801 0 : ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
1802 0 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
1803 : // #i55416#
1804 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1805 : {
1806 0 : bFormatHeightOnly = bOldFormatHeightOnly;
1807 : }
1808 : }
1809 : else
1810 0 : MakeAll();
1811 0 : _InvalidateSize();
1812 0 : InvalidatePos();
1813 0 : if ( bOldLock )
1814 0 : Lock();
1815 0 : const SwRect aNew( GetObjRectWithSpaces() );
1816 0 : if ( aOld != aNew )
1817 0 : ::Notify( this, FindPageFrm(), aOld );
1818 0 : return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
1819 : }
1820 0 : return nDist;
1821 : }
1822 0 : return 0L;
1823 : }
1824 :
1825 0 : SwTwips SwFlyFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
1826 : {
1827 0 : if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
1828 : {
1829 0 : SWRECTFN( this )
1830 0 : SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
1831 0 : if ( nDist > nHeight )
1832 0 : nDist = nHeight;
1833 :
1834 0 : SwTwips nVal = nDist;
1835 0 : if ( IsMinHeight() )
1836 : {
1837 0 : const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
1838 0 : SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
1839 :
1840 0 : nVal = std::min( nDist, nHeight - nFmtHeight );
1841 : }
1842 :
1843 0 : if ( nVal <= 0L )
1844 0 : return 0L;
1845 :
1846 0 : 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 0 : if ( !bTst )
1871 : {
1872 0 : const SwRect aOld( GetObjRectWithSpaces() );
1873 0 : _InvalidateSize();
1874 0 : const sal_Bool bOldLocked = bLocked;
1875 0 : Unlock();
1876 0 : 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 0 : 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 0 : const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
1890 0 : const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
1891 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1892 : {
1893 0 : bFormatHeightOnly = sal_True;
1894 : }
1895 0 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
1896 0 : ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
1897 0 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
1898 : // #i55416#
1899 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1900 : {
1901 0 : bFormatHeightOnly = bOldFormatHeightOnly;
1902 : }
1903 : }
1904 : else
1905 0 : MakeAll();
1906 0 : _InvalidateSize();
1907 0 : InvalidatePos();
1908 0 : if ( bOldLocked )
1909 0 : Lock();
1910 0 : const SwRect aNew( GetObjRectWithSpaces() );
1911 0 : if ( aOld != aNew )
1912 : {
1913 0 : ::Notify( this, FindPageFrm(), aOld );
1914 0 : if ( GetAnchorFrm()->IsInFly() )
1915 0 : AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
1916 : }
1917 0 : return (aOld.*fnRect->fnGetHeight)() -
1918 0 : (aNew.*fnRect->fnGetHeight)();
1919 : }
1920 0 : return nVal;
1921 : }
1922 0 : return 0L;
1923 : }
1924 :
1925 0 : 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 0 : Size aAdjustedNewSize( aNewSize );
1932 : {
1933 0 : if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
1934 0 : Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
1935 0 : static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
1936 : {
1937 0 : SwRect aClipRect;
1938 0 : ::CalcClipRect( GetVirtDrawObj(), aClipRect, sal_False );
1939 0 : if ( aAdjustedNewSize.Width() > aClipRect.Width() )
1940 : {
1941 0 : aAdjustedNewSize.setWidth( aClipRect.Width() );
1942 : }
1943 0 : if ( aAdjustedNewSize.Height() > aClipRect.Height() )
1944 : {
1945 0 : aAdjustedNewSize.setWidth( aClipRect.Height() );
1946 : }
1947 : }
1948 : }
1949 0 : if ( aAdjustedNewSize != Frm().SSize() )
1950 : {
1951 0 : SwFrmFmt *pFmt = GetFmt();
1952 0 : SwFmtFrmSize aSz( pFmt->GetFrmSize() );
1953 0 : aSz.SetWidth( aAdjustedNewSize.Width() );
1954 0 : aSz.SetHeight( aAdjustedNewSize.Height() );
1955 : // go via the Doc for UNDO
1956 0 : pFmt->GetDoc()->SetAttr( aSz, *pFmt );
1957 0 : return aSz.GetSize();
1958 : }
1959 : else
1960 0 : return Frm().SSize();
1961 : }
1962 :
1963 0 : sal_Bool SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const
1964 : {
1965 : OSL_ENSURE( GetAnchorFrm(), "8-( Fly is lost in Space." );
1966 0 : const SwFrm* pFrm = GetAnchorFrm();
1967 0 : do
1968 : {
1969 0 : if ( pFrm == pUpperFrm )
1970 0 : return sal_True;
1971 0 : pFrm = pFrm->IsFlyFrm()
1972 0 : ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
1973 0 : : pFrm->GetUpper();
1974 : } while ( pFrm );
1975 0 : return sal_False;
1976 : }
1977 :
1978 0 : void SwFlyFrm::Cut()
1979 : {
1980 : // TODO: Implement SwFlyFrm::Cut()
1981 0 : }
1982 :
1983 0 : void SwFrm::AppendFly( SwFlyFrm *pNew )
1984 : {
1985 0 : if ( !mpDrawObjs )
1986 0 : mpDrawObjs = new SwSortedObjs();
1987 0 : mpDrawObjs->Insert( *pNew );
1988 0 : pNew->ChgAnchorFrm( this );
1989 :
1990 : // Register at the page
1991 : // If there's none present, register via SwPageFrm::PreparePage
1992 0 : SwPageFrm *pPage = FindPageFrm();
1993 0 : if ( pPage )
1994 : {
1995 0 : 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 0 : SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
2003 0 : if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) )
2004 : {
2005 0 : SwPageFrm *pTmp = pRoot->GetLastPage();
2006 0 : if ( pTmp->GetPhyPageNum() > 30 )
2007 : {
2008 0 : for ( sal_uInt16 i = 0; i < 10; ++i )
2009 : {
2010 0 : pTmp = (SwPageFrm*)pTmp->GetPrev();
2011 0 : if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
2012 0 : break; // So that we don't end up before the Anchor
2013 : }
2014 0 : if ( pTmp->IsEmptyPage() )
2015 0 : pTmp = (SwPageFrm*)pTmp->GetPrev();
2016 0 : pPage = pTmp;
2017 : }
2018 : }
2019 0 : pPage->AppendFlyToPage( pNew );
2020 : }
2021 : else
2022 0 : pPage->AppendFlyToPage( pNew );
2023 : }
2024 0 : }
2025 :
2026 0 : void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
2027 : {
2028 : // Deregister from the page
2029 : // Could already have happened, if the page was already destructed
2030 0 : SwPageFrm *pPage = pToRemove->FindPageFrm();
2031 0 : if ( pPage && pPage->GetSortedObjs() )
2032 : {
2033 0 : pPage->RemoveFlyFromPage( pToRemove );
2034 : }
2035 : // #i73201#
2036 : else
2037 : {
2038 0 : if ( pToRemove->IsAccessibleFrm() &&
2039 0 : pToRemove->GetFmt() &&
2040 0 : !pToRemove->IsFlyInCntFrm() )
2041 : {
2042 0 : SwRootFrm *pRootFrm = getRootFrm();
2043 0 : 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 0 : mpDrawObjs->Remove( *pToRemove );
2055 0 : if ( !mpDrawObjs->Count() )
2056 0 : DELETEZ( mpDrawObjs );
2057 :
2058 0 : pToRemove->ChgAnchorFrm( 0 );
2059 :
2060 0 : if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
2061 0 : GetUpper()->InvalidateSize();
2062 0 : }
2063 :
2064 0 : void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
2065 : {
2066 0 : if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
2067 : {
2068 : OSL_FAIL( "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
2069 0 : return;
2070 : }
2071 :
2072 0 : if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
2073 0 : _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 0 : if ( _rNewObj.GetAnchorFrm() != this )
2082 : {
2083 0 : if ( !mpDrawObjs )
2084 0 : mpDrawObjs = new SwSortedObjs();
2085 0 : mpDrawObjs->Insert( _rNewObj );
2086 0 : _rNewObj.ChgAnchorFrm( this );
2087 : }
2088 :
2089 : // #i113730#
2090 : // Assure the control objects and group objects containing controls are on the control layer
2091 0 : if ( ::CheckControlLayer( _rNewObj.DrawObj() ) )
2092 : {
2093 0 : const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
2094 0 : const SdrLayerID aCurrentLayer(_rNewObj.DrawObj()->GetLayer());
2095 0 : const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
2096 0 : const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
2097 :
2098 0 : 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 0 : _rNewObj.InvalidateObjPos();
2114 :
2115 : // register at page frame
2116 0 : SwPageFrm* pPage = FindPageFrm();
2117 0 : if ( pPage )
2118 : {
2119 0 : pPage->AppendDrawObjToPage( _rNewObj );
2120 : }
2121 :
2122 : // Notify accessible layout.
2123 0 : SwViewShell* pSh = getRootFrm()->GetCurrShell();
2124 0 : if( pSh )
2125 : {
2126 0 : SwRootFrm* pLayout = getRootFrm();
2127 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
2128 0 : pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
2129 : }
2130 : }
2131 :
2132 0 : void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
2133 : {
2134 : // Notify accessible layout.
2135 0 : SwViewShell* pSh = getRootFrm()->GetCurrShell();
2136 0 : if( pSh )
2137 : {
2138 0 : SwRootFrm* pLayout = getRootFrm();
2139 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
2140 0 : pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
2141 : }
2142 :
2143 : // deregister from page frame
2144 0 : SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
2145 0 : if ( pPage && pPage->GetSortedObjs() )
2146 0 : pPage->RemoveDrawObjFromPage( _rToRemoveObj );
2147 :
2148 0 : mpDrawObjs->Remove( _rToRemoveObj );
2149 0 : if ( !mpDrawObjs->Count() )
2150 0 : DELETEZ( mpDrawObjs );
2151 :
2152 0 : _rToRemoveObj.ChgAnchorFrm( 0 );
2153 0 : }
2154 :
2155 0 : void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
2156 : const bool _bNoInvaOfAsCharAnchoredObjs )
2157 : {
2158 0 : 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 0 : const SwPageFrm* pPageFrm = FindPageFrm();
2164 : // #i28701# - re-factoring
2165 0 : sal_uInt32 i = 0;
2166 0 : for ( ; i < GetDrawObjs()->Count(); ++i )
2167 : {
2168 0 : SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2169 0 : if ( _bNoInvaOfAsCharAnchoredObjs &&
2170 0 : (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
2171 : == FLY_AS_CHAR) )
2172 : {
2173 0 : 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 0 : if ( pAnchoredObj->GetPageFrm() &&
2179 0 : pAnchoredObj->GetPageFrm() != pPageFrm )
2180 : {
2181 0 : SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
2182 0 : if ( pAnchorCharFrm &&
2183 0 : 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 0 : 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 0 : if ( pAnchoredObj->ClearedEnvironment() &&
2200 0 : 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 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
2208 : {
2209 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2210 0 : pFly->_Invalidate();
2211 0 : pFly->_InvalidatePos();
2212 0 : if ( !_bInvaPosOnly )
2213 0 : pFly->_InvalidateSize();
2214 : }
2215 : else
2216 : {
2217 0 : pAnchoredObj->InvalidateObjPos();
2218 : }
2219 : } // end of loop on objects, which are connected to the frame
2220 : }
2221 0 : }
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 0 : void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
2229 : {
2230 : // invalidate lower floating screen objects
2231 0 : SwPageFrm* pPageFrm = FindPageFrm();
2232 0 : if ( pPageFrm && pPageFrm->GetSortedObjs() )
2233 : {
2234 0 : SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
2235 0 : for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
2236 : {
2237 0 : 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 0 : const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
2245 0 : if ( pObj->ISA(SwFlyFrm) )
2246 : {
2247 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2248 :
2249 0 : if ( pFly->Frm().Left() == FAR_AWAY )
2250 0 : continue;
2251 :
2252 0 : if ( pFly->IsAnLower( this ) )
2253 0 : 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 0 : const bool bLow = IsAnLower( pAnchorFrm );
2259 0 : if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
2260 : {
2261 0 : pFly->_Invalidate( pPageFrm );
2262 0 : if ( !bLow || pFly->IsFlyAtCntFrm() )
2263 : {
2264 : // #i44016#
2265 0 : if ( _bUnlockPosOfObjs )
2266 : {
2267 0 : pFly->UnlockPosition();
2268 : }
2269 0 : 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 0 : if ( IsAnLower( pAnchorFrm ) ||
2283 0 : pAnchorFrm->FindPageFrm() != pPageFrm )
2284 : {
2285 : // #i44016#
2286 0 : if ( _bUnlockPosOfObjs )
2287 : {
2288 0 : pObj->UnlockPosition();
2289 : }
2290 0 : pObj->InvalidateObjPos();
2291 : }
2292 : }
2293 : }
2294 : }
2295 0 : }
2296 :
2297 0 : void SwFlyFrm::NotifyDrawObj()
2298 : {
2299 0 : SwVirtFlyDrawObj* pObj = GetVirtDrawObj();
2300 0 : pObj->SetRect();
2301 0 : pObj->SetRectsDirty();
2302 0 : pObj->SetChanged();
2303 0 : pObj->BroadcastObjectChange();
2304 0 : if ( GetFmt()->GetSurround().IsContour() )
2305 0 : ClrContourCache( pObj );
2306 0 : }
2307 :
2308 0 : Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
2309 : {
2310 0 : Size aRet( rSz.GetSize() );
2311 :
2312 0 : const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
2313 0 : if( pRel ) // LAYER_IMPL
2314 : {
2315 0 : long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
2316 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
2317 0 : if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
2318 0 : pSh && pSh->GetViewOptions()->getBrowseMode() &&
2319 0 : pSh->VisArea().HasArea() )
2320 : {
2321 0 : nRelWidth = pSh->GetBrowseWidth();
2322 0 : nRelHeight = pSh->VisArea().Height();
2323 0 : Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
2324 0 : long nDiff = nRelWidth - pRel->Prt().Width();
2325 0 : if ( nDiff > 0 )
2326 0 : nRelWidth -= nDiff;
2327 0 : nRelHeight -= 2*aBorder.Height();
2328 0 : nDiff = nRelHeight - pRel->Prt().Height();
2329 0 : 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 0 : if (rSz.GetWidthPercentRelation() != text::RelOrientation::PAGE_FRAME)
2336 0 : nRelWidth = std::min( nRelWidth, pRel->Prt().Width() );
2337 0 : if (rSz.GetHeightPercentRelation() != text::RelOrientation::PAGE_FRAME)
2338 0 : nRelHeight = std::min( nRelHeight, pRel->Prt().Height() );
2339 0 : if( !pRel->IsPageFrm() )
2340 : {
2341 0 : const SwPageFrm* pPage = FindPageFrm();
2342 0 : if( pPage )
2343 : {
2344 0 : if (rSz.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME)
2345 : // Ignore margins of pPage.
2346 0 : nRelWidth = std::min( nRelWidth, pPage->Frm().Width() );
2347 : else
2348 0 : nRelWidth = std::min( nRelWidth, pPage->Prt().Width() );
2349 0 : if (rSz.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME)
2350 : // Ignore margins of pPage.
2351 0 : nRelHeight = std::min( nRelHeight, pPage->Frm().Height() );
2352 : else
2353 0 : nRelHeight = std::min( nRelHeight, pPage->Prt().Height() );
2354 : }
2355 : }
2356 :
2357 0 : if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
2358 0 : aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
2359 0 : if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
2360 0 : aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
2361 :
2362 0 : if ( rSz.GetWidthPercent() == 0xFF )
2363 : {
2364 0 : aRet.Width() *= aRet.Height();
2365 0 : aRet.Width() /= rSz.GetHeight();
2366 : }
2367 0 : else if ( rSz.GetHeightPercent() == 0xFF )
2368 : {
2369 0 : aRet.Height() *= aRet.Width();
2370 0 : aRet.Height() /= rSz.GetWidth();
2371 : }
2372 : }
2373 0 : return aRet;
2374 : }
2375 :
2376 0 : static SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
2377 : {
2378 0 : SwTwips nRet = 0;
2379 0 : SwTwips nMin = 0;
2380 0 : const SwFrm* pFrm = rFrm.Lower();
2381 :
2382 : // No autowidth defined for columned frames
2383 0 : if ( !pFrm || pFrm->IsColumnFrm() )
2384 0 : return nRet;
2385 :
2386 0 : while ( pFrm )
2387 : {
2388 0 : if ( pFrm->IsSctFrm() )
2389 : {
2390 0 : nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
2391 : }
2392 0 : if ( pFrm->IsTxtFrm() )
2393 : {
2394 0 : nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
2395 : const SvxLRSpaceItem &rSpace =
2396 0 : ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
2397 0 : if (!((SwTxtFrm*)pFrm)->IsLocked())
2398 0 : 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 0 : if ( nMin > nRet )
2419 0 : nRet = nMin;
2420 :
2421 0 : pFrm = pFrm->GetNext();
2422 : }
2423 :
2424 0 : return nRet;
2425 : }
2426 :
2427 0 : SwTwips SwFlyFrm::CalcAutoWidth() const
2428 : {
2429 0 : 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 0 : sal_Bool SwFlyFrm::GetContour( PolyPolygon& rContour,
2435 : const sal_Bool _bForPaint ) const
2436 : {
2437 0 : sal_Bool bRet = sal_False;
2438 0 : if( GetFmt()->GetSurround().IsContour() && Lower() &&
2439 0 : Lower()->IsNoTxtFrm() )
2440 : {
2441 0 : 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 0 : const GraphicObject* pGrfObj = NULL;
2446 0 : bool bGrfObjCreated = false;
2447 0 : const SwGrfNode* pGrfNd = pNd->GetGrfNode();
2448 0 : if ( pGrfNd && _bForPaint )
2449 : {
2450 0 : pGrfObj = &(pGrfNd->GetGrfObj());
2451 : }
2452 : else
2453 : {
2454 0 : pGrfObj = new GraphicObject( pNd->GetGraphic() );
2455 0 : bGrfObjCreated = true;
2456 : }
2457 : OSL_ENSURE( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
2458 0 : 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 0 : return bRet;
2532 : }
2533 :
2534 : // OD 2004-03-25 #i26791#
2535 0 : const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
2536 : {
2537 0 : return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
2538 : }
2539 0 : SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
2540 : {
2541 0 : 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 0 : void SwFlyFrm::InvalidateObjPos()
2548 : {
2549 0 : InvalidatePos();
2550 : // #i68520#
2551 0 : InvalidateObjRectWithSpaces();
2552 0 : }
2553 :
2554 0 : SwFrmFmt& SwFlyFrm::GetFrmFmt()
2555 : {
2556 : OSL_ENSURE( GetFmt(),
2557 : "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2558 0 : return *GetFmt();
2559 : }
2560 0 : const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
2561 : {
2562 : OSL_ENSURE( GetFmt(),
2563 : "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2564 0 : return *GetFmt();
2565 : }
2566 :
2567 0 : const SwRect SwFlyFrm::GetObjRect() const
2568 : {
2569 0 : return Frm();
2570 : }
2571 :
2572 : // #i70122#
2573 : // for Writer fly frames the bounding rectangle equals the object rectangles
2574 0 : const SwRect SwFlyFrm::GetObjBoundRect() const
2575 : {
2576 0 : return GetObjRect();
2577 : }
2578 :
2579 : // #i68520#
2580 0 : bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
2581 : {
2582 0 : const bool bChanged( Frm().Pos().getY() != _nTop );
2583 :
2584 0 : Frm().Pos().setY(_nTop);
2585 :
2586 0 : return bChanged;
2587 : }
2588 0 : bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
2589 : {
2590 0 : const bool bChanged( Frm().Pos().getX() != _nLeft );
2591 :
2592 0 : Frm().Pos().setX(_nLeft);
2593 :
2594 0 : 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 0 : bool SwFlyFrm::IsFormatPossible() const
2612 : {
2613 0 : return SwAnchoredObject::IsFormatPossible() &&
2614 0 : !IsLocked() && !IsColLocked();
2615 : }
2616 :
2617 0 : void SwFlyFrm::GetAnchoredObjects( std::list<SwAnchoredObject*>& aList, const SwFmt& rFmt )
2618 : {
2619 0 : SwIterator<SwFlyFrm,SwFmt> aIter( rFmt );
2620 0 : for( SwFlyFrm* pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
2621 0 : aList.push_back( pFlyFrm );
2622 0 : }
2623 :
2624 0 : const SwFlyFrmFmt * SwFlyFrm::GetFmt() const
2625 : {
2626 0 : return static_cast< const SwFlyFrmFmt * >( GetDep() );
2627 : }
2628 :
2629 0 : SwFlyFrmFmt * SwFlyFrm::GetFmt()
2630 : {
2631 0 : return static_cast< SwFlyFrmFmt * >( GetDep() );
2632 : }
2633 :
2634 0 : void SwFlyFrm::Calc() const
2635 : {
2636 0 : if ( !m_bValidContentPos )
2637 0 : ((SwFlyFrm*)this)->PrepareMake();
2638 : else
2639 0 : SwLayoutFrm::Calc();
2640 0 : }
2641 :
2642 0 : SwTwips SwFlyFrm::CalcContentHeight(const SwBorderAttrs *pAttrs, const SwTwips nMinHeight, const SwTwips nUL)
2643 : {
2644 0 : SWRECTFN( this )
2645 0 : SwTwips nHeight = 0;
2646 0 : if ( Lower() )
2647 : {
2648 0 : if ( Lower()->IsColumnFrm() )
2649 : {
2650 0 : FormatWidthCols( *pAttrs, nUL, nMinHeight );
2651 0 : nHeight = (Lower()->Frm().*fnRect->fnGetHeight)();
2652 : }
2653 : else
2654 : {
2655 0 : SwFrm *pFrm = Lower();
2656 0 : while ( pFrm )
2657 : {
2658 0 : nHeight += (pFrm->Frm().*fnRect->fnGetHeight)();
2659 0 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
2660 : // This TxtFrm would like to be a bit larger
2661 0 : nHeight += ((SwTxtFrm*)pFrm)->GetParHeight()
2662 0 : - (pFrm->Prt().*fnRect->fnGetHeight)();
2663 0 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
2664 0 : nHeight += ((SwSectionFrm*)pFrm)->Undersize();
2665 0 : pFrm = pFrm->GetNext();
2666 : }
2667 : }
2668 0 : 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 0 : return nHeight;
2696 : }
2697 :
2698 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|