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 <hintids.hxx>
21 : #include <hints.hxx>
22 : #include <vcl/outdev.hxx>
23 : #include <svl/itemiter.hxx>
24 : #include <editeng/brushitem.hxx>
25 : #include <editeng/keepitem.hxx>
26 : #include <editeng/formatbreakitem.hxx>
27 : #include <fmtornt.hxx>
28 : #include <pagefrm.hxx>
29 : #include <section.hxx>
30 : #include <rootfrm.hxx>
31 : #include <cntfrm.hxx>
32 : #include <dcontact.hxx>
33 : #include <anchoreddrawobject.hxx>
34 : #include <fmtanchr.hxx>
35 : #include <viewsh.hxx>
36 : #include <viewimp.hxx>
37 : #include "viewopt.hxx"
38 : #include <doc.hxx>
39 : #include <fesh.hxx>
40 : #include <docsh.hxx>
41 : #include <flyfrm.hxx>
42 : #include <frmtool.hxx>
43 : #include <ftninfo.hxx>
44 : #include <dflyobj.hxx>
45 : #include <fmtclbl.hxx>
46 : #include <fmtfordr.hxx>
47 : #include <fmtfsize.hxx>
48 : #include <fmtpdsc.hxx>
49 : #include <txtftn.hxx>
50 : #include <fmtftn.hxx>
51 : #include <fmtsrnd.hxx>
52 : #include <ftnfrm.hxx>
53 : #include <tabfrm.hxx>
54 : #include <htmltbl.hxx>
55 : #include <flyfrms.hxx>
56 : #include <sectfrm.hxx>
57 : #include <fmtclds.hxx>
58 : #include <txtfrm.hxx>
59 : #include <ndtxt.hxx>
60 : #include <bodyfrm.hxx>
61 : #include <cellfrm.hxx>
62 : #include <dbg_lay.hxx>
63 : #include <editeng/frmdiritem.hxx>
64 : // OD 2004-05-24 #i28701#
65 : #include <sortedobjs.hxx>
66 : #include <svx/xdef.hxx>
67 :
68 : using namespace ::com::sun::star;
69 :
70 0 : SwFrm::SwFrm( SwModify *pMod, SwFrm* pSib ) :
71 : SwClient( pMod ),
72 : mbIfAccTableShouldDisposing( false ), //A member to identify if the acc table should dispose
73 : // #i65250#
74 : mnFrmId( SwFrm::mnLastFrmId++ ),
75 : mpRoot( pSib ? pSib->getRootFrm() : 0 ),
76 : mpUpper( 0 ),
77 : mpNext( 0 ),
78 : mpPrev( 0 ),
79 : mpDrawObjs( 0 ),
80 : mnType(0),
81 : mbInfBody( sal_False ),
82 : mbInfTab ( sal_False ),
83 : mbInfFly ( sal_False ),
84 : mbInfFtn ( sal_False ),
85 0 : mbInfSct ( sal_False )
86 : {
87 : OSL_ENSURE( pMod, "No frame format given." );
88 0 : mbInvalidR2L = mbInvalidVert = 1;
89 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
90 0 : mbDerivedR2L = mbDerivedVert = mbRightToLeft = mbVertical = mbReverse = mbVertLR = 0;
91 :
92 : mbValidPos = mbValidPrtArea = mbValidSize = mbValidLineNum = mbRetouche =
93 0 : mbFixSize = mbColLocked = sal_False;
94 0 : mbCompletePaint = mbInfInvalid = sal_True;
95 0 : }
96 :
97 0 : const IDocumentDrawModelAccess* SwFrm::getIDocumentDrawModelAccess()
98 : {
99 0 : return GetUpper()->GetFmt()->getIDocumentDrawModelAccess();
100 : }
101 :
102 0 : bool SwFrm::KnowsFormat( const SwFmt& rFmt ) const
103 : {
104 0 : return GetRegisteredIn() == &rFmt;
105 : }
106 :
107 0 : void SwFrm::RegisterToFormat( SwFmt& rFmt )
108 : {
109 0 : rFmt.Add( this );
110 0 : }
111 :
112 0 : void SwFrm::CheckDir( sal_uInt16 nDir, sal_Bool bVert, sal_Bool bOnlyBiDi, sal_Bool bBrowse )
113 : {
114 0 : if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) )
115 : {
116 0 : mbDerivedVert = 1;
117 0 : if( FRMDIR_ENVIRONMENT == nDir )
118 0 : mbDerivedR2L = 1;
119 0 : SetDirFlags( bVert );
120 : }
121 0 : else if( bVert )
122 : {
123 0 : mbInvalidVert = 0;
124 0 : if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
125 0 : || bBrowse )
126 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
127 : {
128 0 : mbVertical = 0;
129 0 : mbVertLR = 0;
130 : }
131 : else
132 : {
133 0 : mbVertical = 1;
134 0 : if(FRMDIR_VERT_TOP_RIGHT == nDir)
135 0 : mbVertLR = 0;
136 0 : else if(FRMDIR_VERT_TOP_LEFT==nDir)
137 0 : mbVertLR = 1;
138 : }
139 : }
140 : else
141 : {
142 0 : mbInvalidR2L = 0;
143 0 : if( FRMDIR_HORI_RIGHT_TOP == nDir )
144 0 : mbRightToLeft = 1;
145 : else
146 0 : mbRightToLeft = 0;
147 : }
148 0 : }
149 :
150 0 : void SwFrm::CheckDirection( bool bVert )
151 : {
152 0 : if( bVert )
153 : {
154 0 : if( !IsHeaderFrm() && !IsFooterFrm() )
155 : {
156 0 : mbDerivedVert = 1;
157 0 : SetDirFlags( bVert );
158 : }
159 : }
160 : else
161 : {
162 0 : mbDerivedR2L = 1;
163 0 : SetDirFlags( bVert );
164 : }
165 0 : }
166 :
167 0 : void SwSectionFrm::CheckDirection( bool bVert )
168 : {
169 0 : const SwFrmFmt* pFmt = GetFmt();
170 0 : if( pFmt )
171 : {
172 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
173 0 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
174 0 : CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
175 0 : bVert, true, bBrowseMode );
176 : }
177 : else
178 0 : SwFrm::CheckDirection( bVert );
179 0 : }
180 :
181 0 : void SwFlyFrm::CheckDirection( bool bVert )
182 : {
183 0 : const SwFrmFmt* pFmt = GetFmt();
184 0 : if( pFmt )
185 : {
186 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
187 0 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
188 0 : CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
189 0 : bVert, false, bBrowseMode );
190 : }
191 : else
192 0 : SwFrm::CheckDirection( bVert );
193 0 : }
194 :
195 0 : void SwTabFrm::CheckDirection( bool bVert )
196 : {
197 0 : const SwFrmFmt* pFmt = GetFmt();
198 0 : if( pFmt )
199 : {
200 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
201 0 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
202 0 : CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
203 0 : bVert, true, bBrowseMode );
204 : }
205 : else
206 0 : SwFrm::CheckDirection( bVert );
207 0 : }
208 :
209 0 : void SwCellFrm::CheckDirection( bool bVert )
210 : {
211 0 : const SwFrmFmt* pFmt = GetFmt();
212 : const SfxPoolItem* pItem;
213 : // Check if the item is set, before actually
214 : // using it. Otherwise the dynamic pool default is used, which may be set
215 : // to LTR in case of OOo 1.0 documents.
216 0 : if( pFmt && SFX_ITEM_SET == pFmt->GetItemState( RES_FRAMEDIR, sal_True, &pItem ) )
217 : {
218 0 : const SvxFrameDirectionItem* pFrmDirItem = static_cast<const SvxFrameDirectionItem*>(pItem);
219 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
220 0 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
221 0 : CheckDir( pFrmDirItem->GetValue(), bVert, false, bBrowseMode );
222 : }
223 : else
224 0 : SwFrm::CheckDirection( bVert );
225 0 : }
226 :
227 0 : void SwTxtFrm::CheckDirection( bool bVert )
228 : {
229 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
230 0 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
231 0 : CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert,
232 0 : true, bBrowseMode );
233 0 : }
234 :
235 0 : void SwFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
236 : {
237 0 : sal_uInt8 nInvFlags = 0;
238 :
239 0 : if( pOld && pNew && RES_ATTRSET_CHG == pNew->Which() )
240 : {
241 0 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
242 0 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
243 : while( true )
244 : {
245 : _UpdateAttrFrm( (SfxPoolItem*)aOIter.GetCurItem(),
246 0 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
247 0 : if( aNIter.IsAtEnd() )
248 0 : break;
249 0 : aNIter.NextItem();
250 0 : aOIter.NextItem();
251 0 : }
252 : }
253 : else
254 0 : _UpdateAttrFrm( pOld, pNew, nInvFlags );
255 :
256 0 : if ( nInvFlags != 0 )
257 : {
258 0 : SwPageFrm *pPage = FindPageFrm();
259 0 : InvalidatePage( pPage );
260 0 : if ( nInvFlags & 0x01 )
261 : {
262 0 : _InvalidatePrt();
263 0 : if( !GetPrev() && IsTabFrm() && IsInSct() )
264 0 : FindSctFrm()->_InvalidatePrt();
265 : }
266 0 : if ( nInvFlags & 0x02 )
267 0 : _InvalidateSize();
268 0 : if ( nInvFlags & 0x04 )
269 0 : _InvalidatePos();
270 0 : if ( nInvFlags & 0x08 )
271 0 : SetCompletePaint();
272 : SwFrm *pNxt;
273 0 : if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
274 : {
275 0 : pNxt->InvalidatePage( pPage );
276 0 : if ( nInvFlags & 0x10 )
277 0 : pNxt->_InvalidatePos();
278 0 : if ( nInvFlags & 0x20 )
279 0 : pNxt->SetCompletePaint();
280 : }
281 : }
282 0 : }
283 :
284 0 : void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
285 : sal_uInt8 &rInvFlags )
286 : {
287 0 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
288 0 : switch( nWhich )
289 : {
290 : case RES_BOX:
291 : case RES_SHADOW:
292 0 : Prepare( PREP_FIXSIZE_CHG );
293 : // no break here!
294 : case RES_LR_SPACE:
295 : case RES_UL_SPACE:
296 0 : rInvFlags |= 0x0B;
297 0 : break;
298 :
299 : case RES_HEADER_FOOTER_EAT_SPACING:
300 0 : rInvFlags |= 0x03;
301 0 : break;
302 :
303 : case RES_BACKGROUND:
304 0 : rInvFlags |= 0x28;
305 0 : break;
306 :
307 : case RES_KEEP:
308 0 : rInvFlags |= 0x04;
309 0 : break;
310 :
311 : case RES_FRM_SIZE:
312 0 : ReinitializeFrmSizeAttrFlags();
313 0 : rInvFlags |= 0x13;
314 0 : break;
315 :
316 : case RES_FMT_CHG:
317 0 : rInvFlags |= 0x0F;
318 0 : break;
319 :
320 : case RES_ROW_SPLIT:
321 : {
322 0 : if ( IsRowFrm() )
323 : {
324 0 : bool bInFollowFlowRow = 0 != IsInFollowFlowRow();
325 0 : if ( bInFollowFlowRow || 0 != IsInSplitTableRow() )
326 : {
327 0 : SwTabFrm* pTab = FindTabFrm();
328 0 : if ( bInFollowFlowRow )
329 0 : pTab = pTab->FindMaster();
330 0 : pTab->SetRemoveFollowFlowLinePending( sal_True );
331 : }
332 : }
333 0 : break;
334 : }
335 : case RES_COL:
336 : OSL_FAIL( "Columns for new FrmTyp?" );
337 0 : break;
338 :
339 : default:
340 : //UUUU the new FillStyle has to do the same as previous RES_BACKGROUND
341 0 : if(nWhich >= XATTR_FILL_FIRST && nWhich <= XATTR_FILL_LAST)
342 : {
343 0 : rInvFlags |= 0x28;
344 : }
345 : /* do Nothing */;
346 : }
347 0 : }
348 :
349 0 : void SwFrm::Prepare( const PrepareHint, const void *, bool )
350 : {
351 : /* Do nothing */
352 0 : }
353 :
354 : /**
355 : * Invalidates the page in which the Frm is currently placed.
356 : * The page is invalidated depending on the type (Layout, Cntnt, FlyFrm)
357 : */
358 0 : void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
359 : {
360 0 : if ( !pPage )
361 : {
362 0 : pPage = FindPageFrm();
363 : // #i28701# - for at-character and as-character
364 : // anchored Writer fly frames additionally invalidate also page frame
365 : // its 'anchor character' is on.
366 0 : if ( pPage && pPage->GetUpper() && IsFlyFrm() )
367 : {
368 0 : const SwFlyFrm* pFlyFrm = static_cast<const SwFlyFrm*>(this);
369 0 : if ( pFlyFrm->IsAutoPos() || pFlyFrm->IsFlyInCntFrm() )
370 : {
371 : // #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
372 : // is replaced by method <FindPageFrmOfAnchor()>. It's return value
373 : // have to be checked.
374 : SwPageFrm* pPageFrmOfAnchor =
375 0 : const_cast<SwFlyFrm*>(pFlyFrm)->FindPageFrmOfAnchor();
376 0 : if ( pPageFrmOfAnchor && pPageFrmOfAnchor != pPage )
377 : {
378 0 : InvalidatePage( pPageFrmOfAnchor );
379 : }
380 : }
381 : }
382 : }
383 :
384 0 : if ( pPage && pPage->GetUpper() )
385 : {
386 0 : if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
387 0 : return;
388 :
389 0 : SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
390 0 : const SwFlyFrm *pFly = FindFlyFrm();
391 0 : if ( IsCntntFrm() )
392 : {
393 0 : if ( pRoot->IsTurboAllowed() )
394 : {
395 : // If a ContentFrame wants to register for a second time, make it a TurboAction.
396 0 : if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
397 0 : pRoot->SetTurbo( (const SwCntntFrm*)this );
398 : else
399 : {
400 0 : pRoot->DisallowTurbo();
401 : //The page of the Turbo could be a different one then mine,
402 : //therefore we have to invalidate it.
403 0 : const SwFrm *pTmp = pRoot->GetTurbo();
404 0 : pRoot->ResetTurbo();
405 0 : pTmp->InvalidatePage();
406 : }
407 : }
408 0 : if ( !pRoot->GetTurbo() )
409 : {
410 0 : if ( pFly )
411 0 : { if( !pFly->IsLocked() )
412 : {
413 0 : if ( pFly->IsFlyInCntFrm() )
414 0 : { pPage->InvalidateFlyInCnt();
415 0 : ((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
416 0 : pFly->GetAnchorFrm()->InvalidatePage();
417 : }
418 : else
419 0 : pPage->InvalidateFlyCntnt();
420 : }
421 : }
422 : else
423 0 : pPage->InvalidateCntnt();
424 : }
425 : }
426 : else
427 : {
428 0 : pRoot->DisallowTurbo();
429 0 : if ( pFly )
430 : {
431 0 : if ( !pFly->IsLocked() )
432 : {
433 0 : if ( pFly->IsFlyInCntFrm() )
434 : {
435 0 : pPage->InvalidateFlyInCnt();
436 0 : ((SwFlyInCntFrm*)pFly)->InvalidateLayout();
437 0 : pFly->GetAnchorFrm()->InvalidatePage();
438 : }
439 : else
440 0 : pPage->InvalidateFlyLayout();
441 : }
442 : }
443 : else
444 0 : pPage->InvalidateLayout();
445 :
446 0 : if ( pRoot->GetTurbo() )
447 0 : { const SwFrm *pTmp = pRoot->GetTurbo();
448 0 : pRoot->ResetTurbo();
449 0 : pTmp->InvalidatePage();
450 : }
451 : }
452 0 : pRoot->SetIdleFlags();
453 :
454 0 : const SwTxtFrm *pTxtFrm = dynamic_cast< const SwTxtFrm * >(this);
455 0 : if (pTxtFrm)
456 : {
457 0 : const SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
458 0 : if (pTxtNode && pTxtNode->IsGrammarCheckDirty())
459 0 : pRoot->SetNeedGrammarCheck( true );
460 : }
461 : }
462 : }
463 :
464 0 : Size SwFrm::ChgSize( const Size& aNewSize )
465 : {
466 0 : mbFixSize = sal_True;
467 0 : const Size aOldSize( Frm().SSize() );
468 0 : if ( aNewSize == aOldSize )
469 0 : return aOldSize;
470 :
471 0 : if ( GetUpper() )
472 : {
473 0 : SWRECTFN2( this )
474 0 : SwRect aNew( Point(0,0), aNewSize );
475 0 : (maFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() );
476 0 : long nNew = (aNew.*fnRect->fnGetHeight)();
477 0 : long nDiff = nNew - (maFrm.*fnRect->fnGetHeight)();
478 0 : if( nDiff )
479 : {
480 0 : if ( GetUpper()->IsFtnBossFrm() && HasFixSize() &&
481 : NA_GROW_SHRINK !=
482 0 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
483 : {
484 0 : (maFrm.*fnRect->fnSetHeight)( nNew );
485 0 : SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff);
486 0 : if ( nReal != nDiff )
487 0 : (maFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal );
488 : }
489 : else
490 : {
491 : // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames
492 : // NOTE: neighbour frames are cell and column frames.
493 0 : if ( !bNeighb )
494 : {
495 0 : if ( nDiff > 0 )
496 0 : Grow( nDiff );
497 : else
498 0 : Shrink( -nDiff );
499 :
500 0 : if ( GetUpper() && (maFrm.*fnRect->fnGetHeight)() != nNew )
501 0 : GetUpper()->_InvalidateSize();
502 : }
503 :
504 : // Even if grow/shrink did not yet set the desired width, for
505 : // example when called by ChgColumns to set the column width, we
506 : // set the right width now.
507 0 : (maFrm.*fnRect->fnSetHeight)( nNew );
508 : }
509 : }
510 : }
511 : else
512 0 : maFrm.SSize( aNewSize );
513 :
514 0 : if ( Frm().SSize() != aOldSize )
515 : {
516 0 : SwPageFrm *pPage = FindPageFrm();
517 0 : if ( GetNext() )
518 : {
519 0 : GetNext()->_InvalidatePos();
520 0 : GetNext()->InvalidatePage( pPage );
521 : }
522 0 : if( IsLayoutFrm() )
523 : {
524 0 : if( IsRightToLeft() )
525 0 : _InvalidatePos();
526 0 : if( ((SwLayoutFrm*)this)->Lower() )
527 0 : ((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
528 : }
529 0 : _InvalidatePrt();
530 0 : _InvalidateSize();
531 0 : InvalidatePage( pPage );
532 : }
533 :
534 0 : return maFrm.SSize();
535 : }
536 :
537 : /** Insert SwFrm into existing structure.
538 : *
539 : * Insertion is done below the parent either before pBehind or
540 : * at the end of the chain if pBehind is empty.
541 : */
542 0 : void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
543 : {
544 : OSL_ENSURE( pParent, "No parent for insert." );
545 : OSL_ENSURE( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
546 : "Frame tree is inconsistent." );
547 :
548 0 : mpUpper = pParent;
549 0 : mpNext = pBehind;
550 0 : if( pBehind )
551 : { //Insert before pBehind.
552 0 : if( 0 != (mpPrev = pBehind->mpPrev) )
553 0 : mpPrev->mpNext = this;
554 : else
555 0 : mpUpper->pLower = this;
556 0 : pBehind->mpPrev = this;
557 : }
558 : else
559 : { //Insert at the end, or as first node in the sub tree
560 0 : mpPrev = mpUpper->Lower();
561 0 : if ( mpPrev )
562 : {
563 0 : while( mpPrev->mpNext )
564 0 : mpPrev = mpPrev->mpNext;
565 0 : mpPrev->mpNext = this;
566 : }
567 : else
568 0 : mpUpper->pLower = this;
569 : }
570 0 : }
571 :
572 : /** Insert SwFrm into existing structure.
573 : *
574 : * Insertion is done below the parent either after pBehind or
575 : * at the beginning of the chain if pBehind is empty.
576 : */
577 0 : void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
578 : {
579 : OSL_ENSURE( pParent, "No Parent for Insert." );
580 : OSL_ENSURE( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
581 : "Frame tree is inconsistent." );
582 :
583 0 : mpUpper = pParent;
584 0 : mpPrev = pBefore;
585 0 : if ( pBefore )
586 : {
587 : //Insert after pBefore
588 0 : if ( 0 != (mpNext = pBefore->mpNext) )
589 0 : mpNext->mpPrev = this;
590 0 : pBefore->mpNext = this;
591 : }
592 : else
593 : {
594 : //Insert at the beginning of the chain
595 0 : mpNext = pParent->Lower();
596 0 : if ( pParent->Lower() )
597 0 : pParent->Lower()->mpPrev = this;
598 0 : pParent->pLower = this;
599 : }
600 0 : }
601 :
602 : /** Insert a chain of SwFrms into an existing struction
603 : *
604 : * Currently, this method is used to insert a SectionFrame (which may have some siblings) into an
605 : * existing structure. If the third parameter is NULL, this method is (besides handling the
606 : * siblings) equal to SwFrm::InsertBefore(..).
607 : *
608 : * If the third parameter is passed, the following happens:
609 : * - this becomes mpNext of pParent
610 : * - pSct becomes mpNext of the last one in the this-chain
611 : * - pBehind is reconnected from pParent to pSct
612 : * The purpose is: a SectionFrm (this) won't become a child of another SectionFrm (pParent), but
613 : * pParent gets split into two siblings (pParent+pSect) and this is inserted between.
614 : */
615 0 : void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
616 : {
617 : OSL_ENSURE( pParent, "No parent for insert." );
618 : OSL_ENSURE( (!pBehind || ( (pBehind && (pParent == pBehind->GetUpper()))
619 : || ((pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm())) ) ),
620 : "Frame tree inconsistent." );
621 0 : if( pSct )
622 : {
623 0 : mpUpper = pParent->GetUpper();
624 0 : SwFrm *pLast = this;
625 0 : while( pLast->GetNext() )
626 : {
627 0 : pLast = pLast->GetNext();
628 0 : pLast->mpUpper = GetUpper();
629 : }
630 0 : if( pBehind )
631 : {
632 0 : pLast->mpNext = pSct;
633 0 : pSct->mpPrev = pLast;
634 0 : pSct->mpNext = pParent->GetNext();
635 : }
636 : else
637 : {
638 0 : pLast->mpNext = pParent->GetNext();
639 0 : if( pLast->GetNext() )
640 0 : pLast->GetNext()->mpPrev = pLast;
641 : }
642 0 : pParent->mpNext = this;
643 0 : mpPrev = pParent;
644 0 : if( pSct->GetNext() )
645 0 : pSct->GetNext()->mpPrev = pSct;
646 0 : while( pLast->GetNext() )
647 : {
648 0 : pLast = pLast->GetNext();
649 0 : pLast->mpUpper = GetUpper();
650 : }
651 0 : if( pBehind )
652 : { // Insert before pBehind.
653 0 : if( pBehind->GetPrev() )
654 0 : pBehind->GetPrev()->mpNext = NULL;
655 : else
656 0 : pBehind->GetUpper()->pLower = NULL;
657 0 : pBehind->mpPrev = NULL;
658 0 : SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
659 0 : if( pTmp->Lower() )
660 : {
661 : OSL_ENSURE( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
662 0 : pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
663 : OSL_ENSURE( pTmp, "InsertGrp: Missing ColBody" );
664 : }
665 0 : pBehind->mpUpper = pTmp;
666 0 : pBehind->GetUpper()->pLower = pBehind;
667 0 : pLast = pBehind->GetNext();
668 0 : while ( pLast )
669 : {
670 0 : pLast->mpUpper = pBehind->GetUpper();
671 0 : pLast = pLast->GetNext();
672 : };
673 : }
674 : else
675 : {
676 : OSL_ENSURE( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
677 0 : delete ((SwSectionFrm*)pSct);
678 : }
679 : }
680 : else
681 : {
682 0 : mpUpper = (SwLayoutFrm*)pParent;
683 0 : SwFrm *pLast = this;
684 0 : while( pLast->GetNext() )
685 : {
686 0 : pLast = pLast->GetNext();
687 0 : pLast->mpUpper = GetUpper();
688 : }
689 0 : pLast->mpNext = pBehind;
690 0 : if( pBehind )
691 : { // Insert before pBehind.
692 0 : if( 0 != (mpPrev = pBehind->mpPrev) )
693 0 : mpPrev->mpNext = this;
694 : else
695 0 : mpUpper->pLower = this;
696 0 : pBehind->mpPrev = pLast;
697 : }
698 : else
699 : {
700 : //Insert at the end, or ... the first node in the subtree
701 0 : mpPrev = mpUpper->Lower();
702 0 : if ( mpPrev )
703 : {
704 0 : while( mpPrev->mpNext )
705 0 : mpPrev = mpPrev->mpNext;
706 0 : mpPrev->mpNext = this;
707 : }
708 : else
709 0 : mpUpper->pLower = this;
710 : }
711 : }
712 0 : }
713 :
714 0 : void SwFrm::Remove()
715 : {
716 : OSL_ENSURE( mpUpper, "Remove without upper?" );
717 :
718 0 : if( mpPrev )
719 : // one out of the middle is removed
720 0 : mpPrev->mpNext = mpNext;
721 : else
722 : { // the first in a list is removed //TODO
723 : OSL_ENSURE( mpUpper->pLower == this, "Layout is inconsistent." );
724 0 : mpUpper->pLower = mpNext;
725 : }
726 0 : if( mpNext )
727 0 : mpNext->mpPrev = mpPrev;
728 :
729 : // Remove link
730 0 : mpNext = mpPrev = 0;
731 0 : mpUpper = 0;
732 0 : }
733 :
734 0 : void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
735 : {
736 : OSL_ENSURE( pParent, "No parent for pasting." );
737 : OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is CntntFrm." );
738 : OSL_ENSURE( pParent != this, "I'm the parent." );
739 : OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
740 : OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
741 : "I'm still registered somewhere" );
742 : OSL_ENSURE( !pSibling || pSibling->IsFlowFrm(),
743 : "<SwCntntFrm::Paste(..)> - sibling not of expected type." );
744 :
745 : //Insert in the tree.
746 0 : InsertBefore( (SwLayoutFrm*)pParent, pSibling );
747 :
748 0 : SwPageFrm *pPage = FindPageFrm();
749 0 : _InvalidateAll();
750 0 : InvalidatePage( pPage );
751 :
752 0 : if( pPage )
753 : {
754 0 : pPage->InvalidateSpelling();
755 0 : pPage->InvalidateSmartTags();
756 0 : pPage->InvalidateAutoCompleteWords();
757 0 : pPage->InvalidateWordCount();
758 : }
759 :
760 0 : if ( GetNext() )
761 : {
762 0 : SwFrm* pNxt = GetNext();
763 0 : pNxt->_InvalidatePrt();
764 0 : pNxt->_InvalidatePos();
765 0 : pNxt->InvalidatePage( pPage );
766 0 : if( pNxt->IsSctFrm() )
767 0 : pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
768 0 : if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
769 0 : pNxt->Prepare( PREP_FTN, 0, false );
770 : }
771 :
772 0 : if ( Frm().Height() )
773 0 : pParent->Grow( Frm().Height() );
774 :
775 0 : if ( Frm().Width() != pParent->Prt().Width() )
776 0 : Prepare( PREP_FIXSIZE_CHG );
777 :
778 0 : if ( GetPrev() )
779 : {
780 0 : if ( IsFollow() )
781 : //I'm a direct follower of my master now
782 0 : ((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
783 : else
784 : {
785 0 : if ( GetPrev()->Frm().Height() !=
786 0 : GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
787 : {
788 : // Take the border into account?
789 0 : GetPrev()->_InvalidatePrt();
790 : }
791 : // OD 18.02.2003 #104989# - force complete paint of previous frame,
792 : // if frame is inserted at the end of a section frame, in order to
793 : // get subsidiary lines repainted for the section.
794 0 : if ( pParent->IsSctFrm() && !GetNext() )
795 : {
796 : // force complete paint of previous frame, if new inserted frame
797 : // in the section is the last one.
798 0 : GetPrev()->SetCompletePaint();
799 : }
800 0 : GetPrev()->InvalidatePage( pPage );
801 : }
802 : }
803 0 : if ( IsInFtn() )
804 : {
805 0 : SwFrm* pFrm = GetIndPrev();
806 0 : if( pFrm && pFrm->IsSctFrm() )
807 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
808 0 : if( pFrm )
809 0 : pFrm->Prepare( PREP_QUOVADIS, 0, false );
810 0 : if( !GetNext() )
811 : {
812 0 : pFrm = FindFtnFrm()->GetNext();
813 0 : if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
814 0 : pFrm->_InvalidatePrt();
815 : }
816 : }
817 :
818 0 : _InvalidateLineNum();
819 0 : SwFrm *pNxt = FindNextCnt();
820 0 : if ( pNxt )
821 : {
822 0 : while ( pNxt && pNxt->IsInTab() )
823 : {
824 0 : if( 0 != (pNxt = pNxt->FindTabFrm()) )
825 0 : pNxt = pNxt->FindNextCnt();
826 : }
827 0 : if ( pNxt )
828 : {
829 0 : pNxt->_InvalidateLineNum();
830 0 : if ( pNxt != GetNext() )
831 0 : pNxt->InvalidatePage();
832 : }
833 : }
834 0 : }
835 :
836 0 : void SwCntntFrm::Cut()
837 : {
838 : OSL_ENSURE( GetUpper(), "Cut without Upper()." );
839 :
840 0 : SwPageFrm *pPage = FindPageFrm();
841 0 : InvalidatePage( pPage );
842 0 : SwFrm *pFrm = GetIndPrev();
843 0 : if( pFrm )
844 : {
845 0 : if( pFrm->IsSctFrm() )
846 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
847 0 : if ( pFrm && pFrm->IsCntntFrm() )
848 : {
849 0 : pFrm->_InvalidatePrt();
850 0 : if( IsInFtn() )
851 0 : pFrm->Prepare( PREP_QUOVADIS, 0, false );
852 : }
853 : // #i26250# - invalidate printing area of previous
854 : // table frame.
855 0 : else if ( pFrm && pFrm->IsTabFrm() )
856 : {
857 0 : pFrm->InvalidatePrt();
858 : }
859 : }
860 :
861 0 : SwFrm *pNxt = FindNextCnt();
862 0 : if ( pNxt )
863 : {
864 0 : while ( pNxt && pNxt->IsInTab() )
865 : {
866 0 : if( 0 != (pNxt = pNxt->FindTabFrm()) )
867 0 : pNxt = pNxt->FindNextCnt();
868 : }
869 0 : if ( pNxt )
870 : {
871 0 : pNxt->_InvalidateLineNum();
872 0 : if ( pNxt != GetNext() )
873 0 : pNxt->InvalidatePage();
874 : }
875 : }
876 :
877 0 : if( 0 != (pFrm = GetIndNext()) )
878 : {
879 : // The old follow may have calculated a gap to the predecessor which
880 : // now becomes obsolete or different as it becomes the first one itself
881 0 : pFrm->_InvalidatePrt();
882 0 : pFrm->_InvalidatePos();
883 0 : pFrm->InvalidatePage( pPage );
884 0 : if( pFrm->IsSctFrm() )
885 : {
886 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
887 0 : if( pFrm )
888 : {
889 0 : pFrm->_InvalidatePrt();
890 0 : pFrm->_InvalidatePos();
891 0 : pFrm->InvalidatePage( pPage );
892 : }
893 : }
894 0 : if( pFrm && IsInFtn() )
895 0 : pFrm->Prepare( PREP_ERGOSUM, 0, false );
896 0 : if( IsInSct() && !GetPrev() )
897 : {
898 0 : SwSectionFrm* pSct = FindSctFrm();
899 0 : if( !pSct->IsFollow() )
900 : {
901 0 : pSct->_InvalidatePrt();
902 0 : pSct->InvalidatePage( pPage );
903 : }
904 : }
905 : }
906 : else
907 : {
908 0 : InvalidateNextPos();
909 : //Someone needs to do the retouching: predecessor or upper
910 0 : if ( 0 != (pFrm = GetPrev()) )
911 0 : { pFrm->SetRetouche();
912 0 : pFrm->Prepare( PREP_WIDOWS_ORPHANS );
913 0 : pFrm->_InvalidatePos();
914 0 : pFrm->InvalidatePage( pPage );
915 : }
916 : // If I'm (was) the only CntntFrm in my upper, it has to do the
917 : // retouching. Also, perhaps a page became empty.
918 : else
919 0 : { SwRootFrm *pRoot = getRootFrm();
920 0 : if ( pRoot )
921 : {
922 0 : pRoot->SetSuperfluous();
923 0 : GetUpper()->SetCompletePaint();
924 0 : GetUpper()->InvalidatePage( pPage );
925 : }
926 0 : if( IsInSct() )
927 : {
928 0 : SwSectionFrm* pSct = FindSctFrm();
929 0 : if( !pSct->IsFollow() )
930 : {
931 0 : pSct->_InvalidatePrt();
932 0 : pSct->InvalidatePage( pPage );
933 : }
934 : }
935 : // #i52253# The master table should take care
936 : // of removing the follow flow line.
937 0 : if ( IsInTab() )
938 : {
939 0 : SwTabFrm* pThisTab = FindTabFrm();
940 0 : SwTabFrm* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : 0;
941 0 : if ( pMasterTab )
942 : {
943 0 : pMasterTab->_InvalidatePos();
944 0 : pMasterTab->SetRemoveFollowFlowLinePending( sal_True );
945 : }
946 : }
947 : }
948 : }
949 : //Remove first, then shrink the upper.
950 0 : SwLayoutFrm *pUp = GetUpper();
951 0 : Remove();
952 0 : if ( pUp )
953 : {
954 0 : SwSectionFrm *pSct = 0;
955 0 : if ( !pUp->Lower() &&
956 0 : ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) ||
957 0 : ( pUp->IsInSct() &&
958 : // #i29438#
959 : // We have to consider the case that the section may be "empty"
960 : // except from a temporary empty table frame.
961 : // This can happen due to the new cell split feature.
962 0 : !pUp->IsCellFrm() &&
963 : // #126020# - adjust check for empty section
964 : // #130797# - correct fix #126020#
965 0 : !(pSct = pUp->FindSctFrm())->ContainsCntnt() &&
966 0 : !pSct->ContainsAny( true ) ) ) )
967 : {
968 0 : if ( pUp->GetUpper() )
969 : {
970 :
971 : // prevent delete of <ColLocked> footnote frame
972 0 : if ( pUp->IsFtnFrm() && !pUp->IsColLocked())
973 : {
974 0 : if( pUp->GetNext() && !pUp->GetPrev() )
975 : {
976 0 : SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
977 0 : if( pTmp )
978 0 : pTmp->_InvalidatePrt();
979 : }
980 0 : pUp->Cut();
981 0 : delete pUp;
982 : }
983 : else
984 : {
985 :
986 0 : if ( pSct->IsColLocked() || !pSct->IsInFtn() ||
987 0 : ( pUp->IsFtnFrm() && pUp->IsColLocked() ) )
988 : {
989 0 : pSct->DelEmpty( sal_False );
990 : // If a locked section may not be deleted then at least
991 : // its size became invalid after removing its last
992 : // content.
993 0 : pSct->_InvalidateSize();
994 : }
995 : else
996 : {
997 0 : pSct->DelEmpty( sal_True );
998 0 : delete pSct;
999 : }
1000 : }
1001 : }
1002 : }
1003 : else
1004 : {
1005 0 : SWRECTFN( this )
1006 0 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1007 0 : if( nFrmHeight )
1008 0 : pUp->Shrink( nFrmHeight );
1009 : }
1010 : }
1011 0 : }
1012 :
1013 0 : void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
1014 : {
1015 : OSL_ENSURE( pParent, "No parent for pasting." );
1016 : OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is CntntFrm." );
1017 : OSL_ENSURE( pParent != this, "I'm the parent oneself." );
1018 : OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
1019 : OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
1020 : "I'm still registered somewhere." );
1021 :
1022 : //Insert in the tree.
1023 0 : InsertBefore( (SwLayoutFrm*)pParent, pSibling );
1024 :
1025 : // OD 24.10.2002 #103517# - correct setting of variable <fnRect>
1026 : // <fnRect> is used for the following:
1027 : // (1) To invalidate the frame's size, if its size, which has to be the
1028 : // same as its upper/parent, differs from its upper's/parent's.
1029 : // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its
1030 : // size, which is not determined by its upper/parent.
1031 : // Which size is which depends on the frame type and the layout direction
1032 : // (vertical or horizontal).
1033 : // There are the following cases:
1034 : // (A) Header and footer frames both in vertical and in horizontal layout
1035 : // have to size the width to the upper/parent. A dimension in the height
1036 : // has to cause a adjustment/grow of the upper/parent.
1037 : // --> <fnRect> = fnRectHori
1038 : // (B) Cell and column frames in vertical layout, the width has to be the
1039 : // same as upper/parent and a dimension in height causes adjustment/grow
1040 : // of the upper/parent.
1041 : // --> <fnRect> = fnRectHori
1042 : // in horizontal layout the other way around
1043 : // --> <fnRect> = fnRectVert
1044 : // (C) Other frames in vertical layout, the height has to be the
1045 : // same as upper/parent and a dimension in width causes adjustment/grow
1046 : // of the upper/parent.
1047 : // --> <fnRect> = fnRectVert
1048 : // in horizontal layout the other way around
1049 : // --> <fnRect> = fnRectHori
1050 : //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert;
1051 : SwRectFn fnRect;
1052 0 : if ( IsHeaderFrm() || IsFooterFrm() )
1053 0 : fnRect = fnRectHori;
1054 0 : else if ( IsCellFrm() || IsColumnFrm() )
1055 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1056 0 : fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert );
1057 : else
1058 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1059 0 : fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
1060 :
1061 0 : if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)())
1062 0 : _InvalidateSize();
1063 0 : _InvalidatePos();
1064 0 : const SwPageFrm *pPage = FindPageFrm();
1065 0 : InvalidatePage( pPage );
1066 : SwFrm *pFrm;
1067 0 : if( !IsColumnFrm() )
1068 : {
1069 0 : if( 0 != ( pFrm = GetIndNext() ) )
1070 : {
1071 0 : pFrm->_InvalidatePos();
1072 0 : if( IsInFtn() )
1073 : {
1074 0 : if( pFrm->IsSctFrm() )
1075 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1076 0 : if( pFrm )
1077 0 : pFrm->Prepare( PREP_ERGOSUM, 0, false );
1078 : }
1079 : }
1080 0 : if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
1081 : {
1082 0 : if( pFrm->IsSctFrm() )
1083 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1084 0 : if( pFrm )
1085 0 : pFrm->Prepare( PREP_QUOVADIS, 0, false );
1086 : }
1087 : }
1088 :
1089 0 : if( (Frm().*fnRect->fnGetHeight)() )
1090 : {
1091 : // AdjustNeighbourhood is now also called in columns which are not
1092 : // placed inside a frame
1093 0 : sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
1094 0 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
1095 0 : : NA_GROW_SHRINK;
1096 0 : SwTwips nGrow = (Frm().*fnRect->fnGetHeight)();
1097 0 : if( NA_ONLY_ADJUST == nAdjust )
1098 0 : AdjustNeighbourhood( nGrow );
1099 : else
1100 : {
1101 0 : SwTwips nReal = 0;
1102 0 : if( NA_ADJUST_GROW == nAdjust )
1103 0 : nReal = AdjustNeighbourhood( nGrow );
1104 0 : if( nReal < nGrow )
1105 0 : nReal += pParent->Grow( nGrow - nReal );
1106 0 : if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
1107 0 : AdjustNeighbourhood( nGrow - nReal );
1108 : }
1109 : }
1110 0 : }
1111 :
1112 0 : void SwLayoutFrm::Cut()
1113 : {
1114 0 : if ( GetNext() )
1115 0 : GetNext()->_InvalidatePos();
1116 :
1117 0 : SWRECTFN( this )
1118 0 : SwTwips nShrink = (Frm().*fnRect->fnGetHeight)();
1119 :
1120 : //Remove first, then shrink upper.
1121 0 : SwLayoutFrm *pUp = GetUpper();
1122 :
1123 : // AdjustNeighbourhood is now also called in columns which are not
1124 : // placed inside a frame
1125 :
1126 : // Remove must not be called before a AdjustNeighbourhood, but it has to
1127 : // be called before the upper-shrink-call, if the upper-shrink takes care
1128 : // of his content
1129 0 : if ( pUp && nShrink )
1130 : {
1131 0 : if( pUp->IsFtnBossFrm() )
1132 : {
1133 0 : sal_uInt8 nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
1134 0 : if( NA_ONLY_ADJUST == nAdjust )
1135 0 : AdjustNeighbourhood( -nShrink );
1136 : else
1137 : {
1138 0 : SwTwips nReal = 0;
1139 0 : if( NA_ADJUST_GROW == nAdjust )
1140 0 : nReal = -AdjustNeighbourhood( -nShrink );
1141 0 : if( nReal < nShrink )
1142 : {
1143 0 : SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)();
1144 0 : (Frm().*fnRect->fnSetHeight)( 0 );
1145 0 : nReal += pUp->Shrink( nShrink - nReal );
1146 0 : (Frm().*fnRect->fnSetHeight)( nOldHeight );
1147 : }
1148 0 : if( NA_GROW_ADJUST == nAdjust && nReal < nShrink )
1149 0 : AdjustNeighbourhood( nReal - nShrink );
1150 : }
1151 0 : Remove();
1152 : }
1153 : else
1154 : {
1155 0 : Remove();
1156 0 : pUp->Shrink( nShrink );
1157 0 : }
1158 : }
1159 : else
1160 0 : Remove();
1161 :
1162 0 : if( pUp && !pUp->Lower() )
1163 : {
1164 0 : pUp->SetCompletePaint();
1165 0 : pUp->InvalidatePage();
1166 : }
1167 0 : }
1168 :
1169 0 : SwTwips SwFrm::Grow( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1170 : {
1171 : OSL_ENSURE( nDist >= 0, "Negative growth?" );
1172 :
1173 : PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )
1174 :
1175 0 : if ( nDist )
1176 : {
1177 0 : SWRECTFN( this )
1178 :
1179 0 : SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1180 0 : if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) )
1181 0 : nDist = LONG_MAX - nPrtHeight;
1182 :
1183 0 : if ( IsFlyFrm() )
1184 0 : return ((SwFlyFrm*)this)->_Grow( nDist, bTst );
1185 0 : else if( IsSctFrm() )
1186 0 : return ((SwSectionFrm*)this)->_Grow( nDist, bTst );
1187 : else
1188 : {
1189 0 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1190 0 : if ( pThisCell )
1191 : {
1192 0 : const SwTabFrm* pTab = FindTabFrm();
1193 :
1194 : // NEW TABLES
1195 0 : if ( pTab->IsVertical() != IsVertical() ||
1196 0 : pThisCell->GetLayoutRowSpan() < 1 )
1197 0 : return 0;
1198 : }
1199 :
1200 0 : const SwTwips nReal = GrowFrm( nDist, bTst, bInfo );
1201 0 : if( !bTst )
1202 : {
1203 0 : nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1204 0 : (Prt().*fnRect->fnSetHeight)( nPrtHeight +
1205 0 : ( IsCntntFrm() ? nDist : nReal ) );
1206 : }
1207 0 : return nReal;
1208 : }
1209 : }
1210 0 : return 0L;
1211 : }
1212 :
1213 0 : SwTwips SwFrm::Shrink( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1214 : {
1215 : OSL_ENSURE( nDist >= 0, "Negative reduction?" );
1216 :
1217 : PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )
1218 :
1219 0 : if ( nDist )
1220 : {
1221 0 : if ( IsFlyFrm() )
1222 0 : return ((SwFlyFrm*)this)->_Shrink( nDist, bTst );
1223 0 : else if( IsSctFrm() )
1224 0 : return ((SwSectionFrm*)this)->_Shrink( nDist, bTst );
1225 : else
1226 : {
1227 0 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1228 0 : if ( pThisCell )
1229 : {
1230 0 : const SwTabFrm* pTab = FindTabFrm();
1231 :
1232 : // NEW TABLES
1233 0 : if ( pTab->IsVertical() != IsVertical() ||
1234 0 : pThisCell->GetLayoutRowSpan() < 1 )
1235 0 : return 0;
1236 : }
1237 :
1238 0 : SWRECTFN( this )
1239 0 : SwTwips nReal = (Frm().*fnRect->fnGetHeight)();
1240 0 : ShrinkFrm( nDist, bTst, bInfo );
1241 0 : nReal -= (Frm().*fnRect->fnGetHeight)();
1242 0 : if( !bTst )
1243 : {
1244 0 : const SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1245 0 : (Prt().*fnRect->fnSetHeight)( nPrtHeight -
1246 0 : ( IsCntntFrm() ? nDist : nReal ) );
1247 : }
1248 0 : return nReal;
1249 : }
1250 : }
1251 0 : return 0L;
1252 : }
1253 :
1254 : /** Adjust surrounding neighbourhood after insertion
1255 : *
1256 : * A Frm needs "normalization" if it is directly placed below a footnote boss (page/column) and its
1257 : * size changes. There is always a frame that takes the maximum possible space (the frame that
1258 : * contains the Body text) and zero or more frames which only take the space needed (header/footer
1259 : * area, footnote container). If one of these frames changes, the body-text-frame has to grow or
1260 : * shrink accordingly, even tough it's fixed.
1261 : *
1262 : * !! Is it possible to do this in a generic way and not restrict it to the page and a distinct
1263 : * frame which takes the maximum space (controlled using the FrmSize attribute)?
1264 : * Problems:
1265 : * - What if multiple frames taking the maximum space are placed next to each other?
1266 : * - How is the maximum space calculated?
1267 : * - How small can those frames become?
1268 : *
1269 : * In any case, only a certain amount of space is allowed, so we never go below a minimum value for
1270 : * the height of the body.
1271 : *
1272 : * @param nDiff the value around which the space has to be allocated
1273 : */
1274 0 : SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, sal_Bool bTst )
1275 : {
1276 : PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );
1277 :
1278 0 : if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // only inside pages/columns
1279 0 : return 0L;
1280 :
1281 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
1282 0 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1283 :
1284 : //The (Page-)Body only changes in BrowseMode, but only if it does not
1285 : //contain columns.
1286 0 : if ( IsPageBodyFrm() && (!bBrowse ||
1287 0 : (((SwLayoutFrm*)this)->Lower() &&
1288 0 : ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
1289 0 : return 0L;
1290 :
1291 : //In BrowseView mode the PageFrm can handle some of the requests.
1292 0 : long nBrowseAdd = 0;
1293 0 : if ( bBrowse && GetUpper()->IsPageFrm() ) // only (Page-)BodyFrms
1294 : {
1295 0 : SwViewShell *pViewShell = getRootFrm()->GetCurrShell();
1296 0 : SwLayoutFrm *pUp = GetUpper();
1297 : long nChg;
1298 0 : const long nUpPrtBottom = pUp->Frm().Height() -
1299 0 : pUp->Prt().Height() - pUp->Prt().Top();
1300 0 : SwRect aInva( pUp->Frm() );
1301 0 : if ( pViewShell )
1302 : {
1303 0 : aInva.Pos().X() = pViewShell->VisArea().Left();
1304 0 : aInva.Width( pViewShell->VisArea().Width() );
1305 : }
1306 0 : if ( nDiff > 0 )
1307 : {
1308 0 : nChg = BROWSE_HEIGHT - pUp->Frm().Height();
1309 0 : nChg = std::min( nDiff, nChg );
1310 :
1311 0 : if ( !IsBodyFrm() )
1312 : {
1313 0 : SetCompletePaint();
1314 0 : if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->Frm().Height() )
1315 : {
1316 : //First minimize Body, it will grow again later.
1317 0 : SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
1318 0 : const long nTmp = nChg - pBody->Prt().Height();
1319 0 : if ( !bTst )
1320 : {
1321 0 : pBody->Frm().Height(std::max( 0L, pBody->Frm().Height() - nChg ));
1322 0 : pBody->_InvalidatePrt();
1323 0 : pBody->_InvalidateSize();
1324 0 : if ( pBody->GetNext() )
1325 0 : pBody->GetNext()->_InvalidatePos();
1326 0 : if ( !IsHeaderFrm() )
1327 0 : pBody->SetCompletePaint();
1328 : }
1329 0 : nChg = nTmp <= 0 ? 0 : nTmp;
1330 : }
1331 : }
1332 :
1333 0 : const long nTmp = nUpPrtBottom + 20;
1334 0 : aInva.Top( aInva.Bottom() - nTmp );
1335 0 : aInva.Height( nChg + nTmp );
1336 : }
1337 : else
1338 : {
1339 : //The page can shrink to 0. The fist page keeps the same size like
1340 : //VisArea.
1341 0 : nChg = nDiff;
1342 0 : long nInvaAdd = 0;
1343 0 : if ( pViewShell && !pUp->GetPrev() &&
1344 0 : pUp->Frm().Height() + nDiff < pViewShell->VisArea().Height() )
1345 : {
1346 : // This means that we have to invalidate adequately.
1347 0 : nChg = pViewShell->VisArea().Height() - pUp->Frm().Height();
1348 0 : nInvaAdd = -(nDiff - nChg);
1349 : }
1350 :
1351 : //Invalidate including bottom border.
1352 0 : long nBorder = nUpPrtBottom + 20;
1353 0 : nBorder -= nChg;
1354 0 : aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
1355 0 : if ( !IsBodyFrm() )
1356 : {
1357 0 : SetCompletePaint();
1358 0 : if ( !IsHeaderFrm() )
1359 0 : ((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
1360 : }
1361 : //Invalidate the page because of the frames. Thereby the page becomes
1362 : //the right size again if a frame didn't fit. This only works
1363 : //randomly for paragraph bound frames otherwise (NotifyFlys).
1364 0 : pUp->InvalidateSize();
1365 : }
1366 0 : if ( !bTst )
1367 : {
1368 : //Independent from nChg
1369 0 : if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
1370 0 : pViewShell->InvalidateWindows( aInva );
1371 : }
1372 0 : if ( !bTst && nChg )
1373 : {
1374 0 : pUp->Frm().SSize().Height() += nChg;
1375 0 : pUp->Prt().SSize().Height() += nChg;
1376 0 : if ( pViewShell )
1377 0 : pViewShell->Imp()->SetFirstVisPageInvalid();
1378 :
1379 0 : if ( GetNext() )
1380 0 : GetNext()->_InvalidatePos();
1381 :
1382 : //Trigger a repaint if necessary.
1383 0 : const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
1384 0 : if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
1385 0 : pViewShell->InvalidateWindows( pUp->Frm() );
1386 :
1387 0 : if ( pUp->GetUpper() )
1388 : {
1389 0 : if ( pUp->GetNext() )
1390 0 : pUp->GetNext()->InvalidatePos();
1391 :
1392 : //Sad but true: during notify on ViewImp a Calc on the page and
1393 : //its Lower may be called. The values should not be changed
1394 : //because the caller takes care of the adjustment of Frm and
1395 : //Prt.
1396 0 : const long nOldFrmHeight = Frm().Height();
1397 0 : const long nOldPrtHeight = Prt().Height();
1398 0 : const sal_Bool bOldComplete = IsCompletePaint();
1399 0 : if ( IsBodyFrm() )
1400 0 : Prt().SSize().Height() = nOldFrmHeight;
1401 :
1402 0 : if ( pUp->GetUpper() )
1403 0 : static_cast<SwRootFrm*>(pUp->GetUpper())->CheckViewLayout( 0, 0 );
1404 : //((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );
1405 :
1406 0 : Frm().SSize().Height() = nOldFrmHeight;
1407 0 : Prt().SSize().Height() = nOldPrtHeight;
1408 0 : mbCompletePaint = bOldComplete;
1409 : }
1410 0 : if ( !IsBodyFrm() )
1411 0 : pUp->_InvalidateSize();
1412 0 : InvalidatePage( (SwPageFrm*)pUp );
1413 : }
1414 0 : nDiff -= nChg;
1415 0 : if ( !nDiff )
1416 0 : return nChg;
1417 : else
1418 0 : nBrowseAdd = nChg;
1419 : }
1420 :
1421 0 : const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
1422 :
1423 0 : SwTwips nReal = 0,
1424 0 : nAdd = 0;
1425 0 : SwFrm *pFrm = 0;
1426 0 : SWRECTFN( this )
1427 :
1428 0 : if( IsBodyFrm() )
1429 : {
1430 0 : if( IsInSct() )
1431 : {
1432 0 : SwSectionFrm *pSect = FindSctFrm();
1433 0 : if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
1434 0 : GetNext()->IsFtnContFrm() )
1435 : {
1436 0 : SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
1437 0 : SwTwips nMinH = 0;
1438 0 : SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
1439 0 : bool bFtn = false;
1440 0 : while( pFtn )
1441 : {
1442 0 : if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
1443 : {
1444 0 : nMinH += (pFtn->Frm().*fnRect->fnGetHeight)();
1445 0 : bFtn = true;
1446 : }
1447 0 : pFtn = (SwFtnFrm*)pFtn->GetNext();
1448 : }
1449 0 : if( bFtn )
1450 0 : nMinH += (pCont->Prt().*fnRect->fnGetTop)();
1451 0 : nReal = (pCont->Frm().*fnRect->fnGetHeight)() - nMinH;
1452 0 : if( nReal > nDiff )
1453 0 : nReal = nDiff;
1454 0 : if( nReal > 0 )
1455 0 : pFrm = GetNext();
1456 : else
1457 0 : nReal = 0;
1458 : }
1459 0 : if( !bTst && !pSect->IsColLocked() )
1460 0 : pSect->InvalidateSize();
1461 : }
1462 0 : if( !pFrm )
1463 0 : return nBrowseAdd;
1464 : }
1465 : else
1466 : {
1467 0 : const bool bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
1468 0 : if ( bFtnPage && !IsFtnContFrm() )
1469 0 : pFrm = (SwFrm*)pBoss->FindFtnCont();
1470 0 : if ( !pFrm )
1471 0 : pFrm = (SwFrm*)pBoss->FindBodyCont();
1472 :
1473 0 : if ( !pFrm )
1474 0 : return 0;
1475 :
1476 : //If not one is found, everything else is solved.
1477 0 : nReal = (pFrm->Frm().*fnRect->fnGetHeight)();
1478 0 : if( nReal > nDiff )
1479 0 : nReal = nDiff;
1480 0 : if( !bFtnPage )
1481 : {
1482 : //Respect the minimal boundary!
1483 0 : if( nReal )
1484 : {
1485 0 : const SwTwips nMax = pBoss->GetVarSpace();
1486 0 : if ( nReal > nMax )
1487 0 : nReal = nMax;
1488 : }
1489 0 : if( !IsFtnContFrm() && nDiff > nReal &&
1490 0 : pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm()
1491 0 : && ( pFrm->GetNext()->IsVertical() == IsVertical() )
1492 : )
1493 : {
1494 : //If the Body doesn't return enough, we look for a footnote, if
1495 : //there is one, we steal there accordingly.
1496 0 : const SwTwips nAddMax = (pFrm->GetNext()->Frm().*fnRect->
1497 0 : fnGetHeight)();
1498 0 : nAdd = nDiff - nReal;
1499 0 : if ( nAdd > nAddMax )
1500 0 : nAdd = nAddMax;
1501 0 : if ( !bTst )
1502 : {
1503 0 : (pFrm->GetNext()->Frm().*fnRect->fnSetHeight)(nAddMax-nAdd);
1504 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1505 0 : if( bVert && !bVertL2R && !bRev )
1506 0 : pFrm->GetNext()->Frm().Pos().X() += nAdd;
1507 0 : pFrm->GetNext()->InvalidatePrt();
1508 0 : if ( pFrm->GetNext()->GetNext() )
1509 0 : pFrm->GetNext()->GetNext()->_InvalidatePos();
1510 : }
1511 : }
1512 : }
1513 : }
1514 :
1515 0 : if ( !bTst && nReal )
1516 : {
1517 0 : SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)();
1518 0 : (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal );
1519 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1520 0 : if( bVert && !bVertL2R && !bRev )
1521 0 : pFrm->Frm().Pos().X() += nReal;
1522 0 : pFrm->InvalidatePrt();
1523 0 : if ( pFrm->GetNext() )
1524 0 : pFrm->GetNext()->_InvalidatePos();
1525 0 : if( nReal < 0 && pFrm->IsInSct() )
1526 : {
1527 0 : SwLayoutFrm* pUp = pFrm->GetUpper();
1528 0 : if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
1529 0 : !pUp->IsColLocked() )
1530 0 : pUp->InvalidateSize();
1531 : }
1532 0 : if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
1533 : {
1534 0 : const SwSortedObjs &rObjs = *pBoss->GetDrawObjs();
1535 : OSL_ENSURE( pBoss->IsPageFrm(), "Header/Footer out of page?" );
1536 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1537 : {
1538 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
1539 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
1540 : {
1541 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1542 : OSL_ENSURE( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
1543 : const SwFmtVertOrient &rVert =
1544 0 : pFly->GetFmt()->GetVertOrient();
1545 : // When do we have to invalidate?
1546 : // If a frame is aligned on a PageTextArea and the header
1547 : // changes a TOP, MIDDLE or NONE aligned frame needs to
1548 : // recalculate it's position; if the footer changes a BOTTOM
1549 : // or MIDDLE aligned frame needs to recalculate it's
1550 : // position.
1551 0 : if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
1552 0 : rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) &&
1553 0 : ((IsHeaderFrm() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
1554 0 : (IsFooterFrm() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
1555 0 : rVert.GetVertOrient() != text::VertOrientation::TOP)) )
1556 : {
1557 0 : pFly->_InvalidatePos();
1558 0 : pFly->_Invalidate();
1559 : }
1560 : }
1561 : }
1562 : }
1563 : }
1564 0 : return (nBrowseAdd + nReal + nAdd);
1565 : }
1566 :
1567 : /** method to perform additional actions on an invalidation (2004-05-19 #i28701#) */
1568 0 : void SwFrm::_ActionOnInvalidation( const InvalidationType )
1569 : {
1570 : // default behaviour is to perform no additional action
1571 0 : }
1572 :
1573 : /** method to determine, if an invalidation is allowed (2004-05-19 #i28701#) */
1574 0 : bool SwFrm::_InvalidationAllowed( const InvalidationType ) const
1575 : {
1576 : // default behaviour is to allow invalidation
1577 0 : return true;
1578 : }
1579 :
1580 0 : void SwFrm::ImplInvalidateSize()
1581 : {
1582 0 : if ( _InvalidationAllowed( INVALID_SIZE ) )
1583 : {
1584 0 : mbValidSize = sal_False;
1585 0 : if ( IsFlyFrm() )
1586 0 : ((SwFlyFrm*)this)->_Invalidate();
1587 : else
1588 0 : InvalidatePage();
1589 :
1590 : // OD 2004-05-19 #i28701#
1591 0 : _ActionOnInvalidation( INVALID_SIZE );
1592 : }
1593 0 : }
1594 :
1595 0 : void SwFrm::ImplInvalidatePrt()
1596 : {
1597 0 : if ( _InvalidationAllowed( INVALID_PRTAREA ) )
1598 : {
1599 0 : mbValidPrtArea = sal_False;
1600 0 : if ( IsFlyFrm() )
1601 0 : ((SwFlyFrm*)this)->_Invalidate();
1602 : else
1603 0 : InvalidatePage();
1604 :
1605 : // OD 2004-05-19 #i28701#
1606 0 : _ActionOnInvalidation( INVALID_PRTAREA );
1607 : }
1608 0 : }
1609 :
1610 0 : void SwFrm::ImplInvalidatePos()
1611 : {
1612 0 : if ( _InvalidationAllowed( INVALID_POS ) )
1613 : {
1614 0 : mbValidPos = sal_False;
1615 0 : if ( IsFlyFrm() )
1616 : {
1617 0 : ((SwFlyFrm*)this)->_Invalidate();
1618 : }
1619 : else
1620 : {
1621 0 : InvalidatePage();
1622 : }
1623 :
1624 : // OD 2004-05-19 #i28701#
1625 0 : _ActionOnInvalidation( INVALID_POS );
1626 : }
1627 0 : }
1628 :
1629 0 : void SwFrm::ImplInvalidateLineNum()
1630 : {
1631 0 : if ( _InvalidationAllowed( INVALID_LINENUM ) )
1632 : {
1633 0 : mbValidLineNum = sal_False;
1634 : OSL_ENSURE( IsTxtFrm(), "line numbers are implemented for text only" );
1635 0 : InvalidatePage();
1636 :
1637 : // OD 2004-05-19 #i28701#
1638 0 : _ActionOnInvalidation( INVALID_LINENUM );
1639 : }
1640 0 : }
1641 :
1642 0 : void SwFrm::ReinitializeFrmSizeAttrFlags()
1643 : {
1644 0 : const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
1645 0 : if ( ATT_VAR_SIZE == rFmtSize.GetHeightSizeType() ||
1646 0 : ATT_MIN_SIZE == rFmtSize.GetHeightSizeType())
1647 : {
1648 0 : mbFixSize = sal_False;
1649 0 : if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
1650 : {
1651 0 : SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
1652 0 : while ( pFrm )
1653 0 : { pFrm->_InvalidateSize();
1654 0 : pFrm->_InvalidatePrt();
1655 0 : pFrm = pFrm->GetNext();
1656 : }
1657 0 : SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
1658 : // #i36991# - be save.
1659 : // E.g., a row can contain *no* content.
1660 0 : if ( pCnt )
1661 : {
1662 0 : pCnt->InvalidatePage();
1663 0 : do
1664 : {
1665 0 : pCnt->Prepare( PREP_ADJUST_FRM );
1666 0 : pCnt->_InvalidateSize();
1667 0 : pCnt = pCnt->GetNextCntntFrm();
1668 0 : } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
1669 : }
1670 : }
1671 : }
1672 0 : else if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
1673 : {
1674 0 : if( IsVertical() )
1675 0 : ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
1676 : else
1677 0 : ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
1678 : }
1679 0 : }
1680 :
1681 0 : void SwFrm::ValidateThisAndAllLowers( const sal_uInt16 nStage )
1682 : {
1683 : // Stage 0: Only validate frames. Do not process any objects.
1684 : // Stage 1: Only validate fly frames and all of their contents.
1685 : // Stage 2: Validate all.
1686 :
1687 0 : const bool bOnlyObject = 1 == nStage;
1688 0 : const bool bIncludeObjects = 1 <= nStage;
1689 :
1690 0 : if ( !bOnlyObject || ISA(SwFlyFrm) )
1691 : {
1692 0 : mbValidSize = sal_True;
1693 0 : mbValidPrtArea = sal_True;
1694 0 : mbValidPos = sal_True;
1695 : }
1696 :
1697 0 : if ( bIncludeObjects )
1698 : {
1699 0 : const SwSortedObjs* pObjs = GetDrawObjs();
1700 0 : if ( pObjs )
1701 : {
1702 0 : const sal_uInt32 nCnt = pObjs->Count();
1703 0 : for ( sal_uInt32 i = 0; i < nCnt; ++i )
1704 : {
1705 0 : SwAnchoredObject* pAnchObj = (*pObjs)[i];
1706 0 : if ( pAnchObj->ISA(SwFlyFrm) )
1707 0 : static_cast<SwFlyFrm*>(pAnchObj)->ValidateThisAndAllLowers( 2 );
1708 0 : else if ( pAnchObj->ISA(SwAnchoredDrawObject) )
1709 0 : static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis();
1710 : }
1711 : }
1712 : }
1713 :
1714 0 : if ( IsLayoutFrm() )
1715 : {
1716 0 : SwFrm* pLower = static_cast<SwLayoutFrm*>(this)->Lower();
1717 0 : while ( pLower )
1718 : {
1719 0 : pLower->ValidateThisAndAllLowers( nStage );
1720 0 : pLower = pLower->GetNext();
1721 : }
1722 : }
1723 0 : }
1724 :
1725 0 : SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1726 : {
1727 0 : SWRECTFN( this )
1728 :
1729 0 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1730 0 : if( nFrmHeight > 0 &&
1731 0 : nDist > (LONG_MAX - nFrmHeight ) )
1732 0 : nDist = LONG_MAX - nFrmHeight;
1733 :
1734 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
1735 0 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1736 0 : const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse with Body
1737 0 : if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
1738 : {
1739 0 : if ( !bTst )
1740 : {
1741 0 : (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
1742 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1743 0 : if( IsVertical() && !IsVertLR() && !IsReverse() )
1744 0 : Frm().Pos().X() -= nDist;
1745 0 : if ( GetNext() )
1746 : {
1747 0 : GetNext()->InvalidatePos();
1748 : }
1749 : // #i28701# - Due to the new object positioning the
1750 : // frame on the next page/column can flow backward (e.g. it was moved forward
1751 : // due to the positioning of its objects ). Thus, invalivate this next frame,
1752 : // if document compatibility option 'Consider wrapping style influence on
1753 : // object positioning' is ON.
1754 0 : else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1755 : {
1756 0 : InvalidateNextPos();
1757 : }
1758 : }
1759 0 : return 0;
1760 : }
1761 :
1762 0 : SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)();
1763 0 : SwFrm *pFrm = GetUpper()->Lower();
1764 0 : while( pFrm && nReal > 0 )
1765 0 : { nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
1766 0 : pFrm = pFrm->GetNext();
1767 : }
1768 :
1769 0 : if ( !bTst )
1770 : {
1771 : //Cntnts are always resized to the wished value.
1772 0 : long nOld = (Frm().*fnRect->fnGetHeight)();
1773 0 : (Frm().*fnRect->fnSetHeight)( nOld + nDist );
1774 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1775 0 : if( IsVertical()&& !IsVertLR() && !IsReverse() )
1776 0 : Frm().Pos().X() -= nDist;
1777 0 : if ( nOld && IsInTab() )
1778 : {
1779 0 : SwTabFrm *pTab = FindTabFrm();
1780 0 : if ( pTab->GetTable()->GetHTMLTableLayout() &&
1781 0 : !pTab->IsJoinLocked() &&
1782 0 : !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
1783 : {
1784 0 : pTab->InvalidatePos();
1785 0 : pTab->SetResizeHTMLTable();
1786 : }
1787 : }
1788 : }
1789 :
1790 : //Only grow Upper if necessary.
1791 0 : if ( nReal < nDist )
1792 : {
1793 0 : if( GetUpper() )
1794 : {
1795 0 : if( bTst || !GetUpper()->IsFooterFrm() )
1796 0 : nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
1797 0 : bTst, bInfo );
1798 : else
1799 : {
1800 0 : nReal = 0;
1801 0 : GetUpper()->InvalidateSize();
1802 : }
1803 : }
1804 : else
1805 0 : nReal = 0;
1806 : }
1807 : else
1808 0 : nReal = nDist;
1809 :
1810 : // #i28701# - Due to the new object positioning the
1811 : // frame on the next page/column can flow backward (e.g. it was moved forward
1812 : // due to the positioning of its objects ). Thus, invalivate this next frame,
1813 : // if document compatibility option 'Consider wrapping style influence on
1814 : // object positioning' is ON.
1815 0 : if ( !bTst )
1816 : {
1817 0 : if ( GetNext() )
1818 : {
1819 0 : GetNext()->InvalidatePos();
1820 : }
1821 0 : else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1822 : {
1823 0 : InvalidateNextPos();
1824 : }
1825 : }
1826 :
1827 0 : return nReal;
1828 : }
1829 :
1830 0 : SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1831 : {
1832 0 : SWRECTFN( this )
1833 : OSL_ENSURE( nDist >= 0, "nDist < 0" );
1834 : OSL_ENSURE( nDist <= (Frm().*fnRect->fnGetHeight)(),
1835 : "nDist > than current size." );
1836 :
1837 0 : if ( !bTst )
1838 : {
1839 : SwTwips nRstHeight;
1840 0 : if( GetUpper() )
1841 0 : nRstHeight = (Frm().*fnRect->fnBottomDist)
1842 0 : ( (GetUpper()->*fnRect->fnGetPrtBottom)() );
1843 : else
1844 0 : nRstHeight = 0;
1845 0 : if( nRstHeight < 0 )
1846 : {
1847 0 : SwTwips nNextHeight = 0;
1848 0 : if( GetUpper()->IsSctFrm() && nDist > LONG_MAX/2 )
1849 : {
1850 0 : SwFrm *pNxt = GetNext();
1851 0 : while( pNxt )
1852 : {
1853 0 : nNextHeight += (pNxt->Frm().*fnRect->fnGetHeight)();
1854 0 : pNxt = pNxt->GetNext();
1855 : }
1856 : }
1857 0 : nRstHeight = nDist + nRstHeight - nNextHeight;
1858 : }
1859 : else
1860 0 : nRstHeight = nDist;
1861 0 : (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist );
1862 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1863 0 : if( IsVertical() && !IsVertLR() )
1864 0 : Frm().Pos().X() += nDist;
1865 0 : nDist = nRstHeight;
1866 0 : if ( IsInTab() )
1867 : {
1868 0 : SwTabFrm *pTab = FindTabFrm();
1869 0 : if ( pTab->GetTable()->GetHTMLTableLayout() &&
1870 0 : !pTab->IsJoinLocked() &&
1871 0 : !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
1872 : {
1873 0 : pTab->InvalidatePos();
1874 0 : pTab->SetResizeHTMLTable();
1875 : }
1876 : }
1877 : }
1878 :
1879 : SwTwips nReal;
1880 0 : if( GetUpper() && nDist > 0 )
1881 : {
1882 0 : if( bTst || !GetUpper()->IsFooterFrm() )
1883 0 : nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
1884 : else
1885 : {
1886 0 : nReal = 0;
1887 :
1888 : // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
1889 : // if there are any objects anchored inside your content, which
1890 : // overlap with the shrinking frame.
1891 : // This may lead to a footer frame that is too big, but this is better
1892 : // than looping.
1893 : // #109722# : The fix for #108745# was too strict.
1894 :
1895 0 : bool bInvalidate = true;
1896 0 : const SwRect aRect( Frm() );
1897 0 : const SwPageFrm* pPage = FindPageFrm();
1898 0 : const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : 0;
1899 0 : if( pSorted )
1900 : {
1901 0 : for ( sal_uInt16 i = 0; i < pSorted->Count(); ++i )
1902 : {
1903 0 : const SwAnchoredObject* pAnchoredObj = (*pSorted)[i];
1904 0 : const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
1905 :
1906 0 : if( aBound.Left() > aRect.Right() )
1907 0 : continue;
1908 :
1909 0 : if( aBound.IsOver( aRect ) )
1910 : {
1911 0 : const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1912 0 : if( SURROUND_THROUGHT != rFmt.GetSurround().GetSurround() )
1913 : {
1914 0 : const SwFrm* pAnchor = pAnchoredObj->GetAnchorFrm();
1915 0 : if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
1916 : {
1917 0 : bInvalidate = false;
1918 0 : break;
1919 : }
1920 : }
1921 : }
1922 : }
1923 : }
1924 :
1925 0 : if ( bInvalidate )
1926 0 : GetUpper()->InvalidateSize();
1927 : }
1928 : }
1929 : else
1930 0 : nReal = 0;
1931 :
1932 0 : if ( !bTst )
1933 : {
1934 : //The position of the next Frm changes for sure.
1935 0 : InvalidateNextPos();
1936 :
1937 : //If I don't have a successor I have to do the retouch by myself.
1938 0 : if ( !GetNext() )
1939 0 : SetRetouche();
1940 : }
1941 0 : return nReal;
1942 : }
1943 :
1944 0 : void SwCntntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
1945 : {
1946 0 : sal_uInt8 nInvFlags = 0;
1947 :
1948 0 : if( pNew && RES_ATTRSET_CHG == pNew->Which() )
1949 : {
1950 0 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
1951 0 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
1952 0 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
1953 0 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
1954 : while( true )
1955 : {
1956 : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
1957 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
1958 0 : &aOldSet, &aNewSet );
1959 0 : if( aNIter.IsAtEnd() )
1960 0 : break;
1961 0 : aNIter.NextItem();
1962 0 : aOIter.NextItem();
1963 : }
1964 0 : if ( aOldSet.Count() || aNewSet.Count() )
1965 0 : SwFrm::Modify( &aOldSet, &aNewSet );
1966 : }
1967 : else
1968 0 : _UpdateAttr( pOld, pNew, nInvFlags );
1969 :
1970 0 : if ( nInvFlags != 0 )
1971 : {
1972 0 : SwPageFrm *pPage = FindPageFrm();
1973 0 : InvalidatePage( pPage );
1974 0 : if ( nInvFlags & 0x01 )
1975 0 : SetCompletePaint();
1976 0 : if ( nInvFlags & 0x02 )
1977 0 : _InvalidatePos();
1978 0 : if ( nInvFlags & 0x04 )
1979 0 : _InvalidateSize();
1980 0 : if ( nInvFlags & 0x88 )
1981 : {
1982 0 : if( IsInSct() && !GetPrev() )
1983 : {
1984 0 : SwSectionFrm *pSect = FindSctFrm();
1985 0 : if( pSect->ContainsAny() == this )
1986 : {
1987 0 : pSect->_InvalidatePrt();
1988 0 : pSect->InvalidatePage( pPage );
1989 : }
1990 : }
1991 0 : _InvalidatePrt();
1992 : }
1993 0 : SwFrm* mpNextFrm = GetIndNext();
1994 0 : if ( mpNextFrm && nInvFlags & 0x10)
1995 : {
1996 0 : mpNextFrm->_InvalidatePrt();
1997 0 : mpNextFrm->InvalidatePage( pPage );
1998 : }
1999 0 : if ( mpNextFrm && nInvFlags & 0x80 )
2000 : {
2001 0 : mpNextFrm->SetCompletePaint();
2002 : }
2003 0 : if ( nInvFlags & 0x20 )
2004 : {
2005 0 : SwFrm* pPrevFrm = GetPrev();
2006 0 : if ( pPrevFrm )
2007 : {
2008 0 : pPrevFrm->_InvalidatePrt();
2009 0 : pPrevFrm->InvalidatePage( pPage );
2010 : }
2011 : }
2012 0 : if ( nInvFlags & 0x40 )
2013 0 : InvalidateNextPos();
2014 : }
2015 0 : }
2016 :
2017 0 : void SwCntntFrm::_UpdateAttr( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
2018 : sal_uInt8 &rInvFlags,
2019 : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2020 : {
2021 0 : bool bClear = true;
2022 0 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2023 0 : switch ( nWhich )
2024 : {
2025 : case RES_FMT_CHG:
2026 0 : rInvFlags = 0xFF;
2027 : /* no break here */
2028 :
2029 : case RES_PAGEDESC: //attribute changes (on/off)
2030 0 : if ( IsInDocBody() && !IsInTab() )
2031 : {
2032 0 : rInvFlags |= 0x02;
2033 0 : SwPageFrm *pPage = FindPageFrm();
2034 0 : if ( !GetPrev() )
2035 0 : CheckPageDescs( pPage );
2036 0 : if ( GetAttrSet()->GetPageDesc().GetNumOffset() )
2037 0 : ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( sal_True );
2038 0 : SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
2039 0 : pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
2040 : }
2041 0 : break;
2042 :
2043 : case RES_UL_SPACE:
2044 : {
2045 : // OD 2004-02-18 #106629# - correction
2046 : // Invalidation of the printing area of next frame, not only
2047 : // for footnote content.
2048 0 : if ( !GetIndNext() )
2049 : {
2050 0 : SwFrm* pNxt = FindNext();
2051 0 : if ( pNxt )
2052 : {
2053 0 : SwPageFrm* pPg = pNxt->FindPageFrm();
2054 0 : pNxt->InvalidatePage( pPg );
2055 0 : pNxt->_InvalidatePrt();
2056 0 : if( pNxt->IsSctFrm() )
2057 : {
2058 0 : SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2059 0 : if( pCnt )
2060 : {
2061 0 : pCnt->_InvalidatePrt();
2062 0 : pCnt->InvalidatePage( pPg );
2063 : }
2064 : }
2065 0 : pNxt->SetCompletePaint();
2066 : }
2067 : }
2068 : // OD 2004-03-17 #i11860#
2069 0 : if ( GetIndNext() &&
2070 0 : !GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
2071 : {
2072 : // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
2073 0 : GetIndNext()->InvalidateObjs( true );
2074 : }
2075 0 : Prepare( PREP_UL_SPACE ); //TxtFrm has to correct line spacing.
2076 0 : rInvFlags |= 0x80;
2077 : /* no break here */
2078 : }
2079 : case RES_LR_SPACE:
2080 : case RES_BOX:
2081 : case RES_SHADOW:
2082 0 : Prepare( PREP_FIXSIZE_CHG );
2083 0 : SwFrm::Modify( pOld, pNew );
2084 0 : rInvFlags |= 0x30;
2085 0 : break;
2086 :
2087 : case RES_BREAK:
2088 : {
2089 0 : rInvFlags |= 0x42;
2090 0 : const IDocumentSettingAccess* pIDSA = GetUpper()->GetFmt()->getIDocumentSettingAccess();
2091 0 : if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
2092 0 : pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) )
2093 : {
2094 0 : rInvFlags |= 0x1;
2095 0 : SwFrm* pNxt = FindNext();
2096 0 : if( pNxt )
2097 : {
2098 0 : SwPageFrm* pPg = pNxt->FindPageFrm();
2099 0 : pNxt->InvalidatePage( pPg );
2100 0 : pNxt->_InvalidatePrt();
2101 0 : if( pNxt->IsSctFrm() )
2102 : {
2103 0 : SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2104 0 : if( pCnt )
2105 : {
2106 0 : pCnt->_InvalidatePrt();
2107 0 : pCnt->InvalidatePage( pPg );
2108 : }
2109 : }
2110 0 : pNxt->SetCompletePaint();
2111 : }
2112 : }
2113 : }
2114 0 : break;
2115 :
2116 : // OD 2004-02-26 #i25029#
2117 : case RES_PARATR_CONNECT_BORDER:
2118 : {
2119 0 : rInvFlags |= 0x01;
2120 0 : if ( IsTxtFrm() )
2121 : {
2122 0 : InvalidateNextPrtArea();
2123 : }
2124 0 : if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
2125 : {
2126 0 : FindTabFrm()->InvalidateSize();
2127 : }
2128 : }
2129 0 : break;
2130 :
2131 : case RES_PARATR_TABSTOP:
2132 : case RES_CHRATR_PROPORTIONALFONTSIZE:
2133 : case RES_CHRATR_SHADOWED:
2134 : case RES_CHRATR_AUTOKERN:
2135 : case RES_CHRATR_UNDERLINE:
2136 : case RES_CHRATR_OVERLINE:
2137 : case RES_CHRATR_KERNING:
2138 : case RES_CHRATR_FONT:
2139 : case RES_CHRATR_FONTSIZE:
2140 : case RES_CHRATR_ESCAPEMENT:
2141 : case RES_CHRATR_CONTOUR:
2142 : case RES_PARATR_NUMRULE:
2143 0 : rInvFlags |= 0x01;
2144 0 : break;
2145 :
2146 : case RES_FRM_SIZE:
2147 0 : rInvFlags |= 0x01;
2148 : /* no break here */
2149 :
2150 : default:
2151 0 : bClear = false;
2152 : }
2153 0 : if ( bClear )
2154 : {
2155 0 : if ( pOldSet || pNewSet )
2156 : {
2157 0 : if ( pOldSet )
2158 0 : pOldSet->ClearItem( nWhich );
2159 0 : if ( pNewSet )
2160 0 : pNewSet->ClearItem( nWhich );
2161 : }
2162 : else
2163 0 : SwFrm::Modify( pOld, pNew );
2164 : }
2165 0 : }
2166 :
2167 0 : SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt, SwFrm* pSib ):
2168 : SwFrm( pFmt, pSib ),
2169 0 : pLower( 0 )
2170 : {
2171 0 : const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
2172 0 : if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
2173 0 : mbFixSize = sal_True;
2174 0 : }
2175 :
2176 : // #i28701#
2177 0 : TYPEINIT1(SwLayoutFrm,SwFrm);
2178 :
2179 0 : SwTwips SwLayoutFrm::InnerHeight() const
2180 : {
2181 0 : if( !Lower() )
2182 0 : return 0;
2183 0 : SwTwips nRet = 0;
2184 0 : const SwFrm* pCnt = Lower();
2185 0 : SWRECTFN( this )
2186 0 : if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
2187 : {
2188 0 : do
2189 : {
2190 0 : SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight();
2191 0 : if( pCnt->GetValidPrtAreaFlag() )
2192 0 : nTmp += (pCnt->Frm().*fnRect->fnGetHeight)() -
2193 0 : (pCnt->Prt().*fnRect->fnGetHeight)();
2194 0 : if( nRet < nTmp )
2195 0 : nRet = nTmp;
2196 0 : pCnt = pCnt->GetNext();
2197 : } while ( pCnt );
2198 : }
2199 : else
2200 : {
2201 0 : do
2202 : {
2203 0 : nRet += (pCnt->Frm().*fnRect->fnGetHeight)();
2204 0 : if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
2205 0 : nRet += ((SwTxtFrm*)pCnt)->GetParHeight() -
2206 0 : (pCnt->Prt().*fnRect->fnGetHeight)();
2207 0 : if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
2208 0 : nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() -
2209 0 : (pCnt->Prt().*fnRect->fnGetHeight)();
2210 0 : pCnt = pCnt->GetNext();
2211 : } while( pCnt );
2212 :
2213 : }
2214 0 : return nRet;
2215 : }
2216 :
2217 0 : SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2218 : {
2219 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
2220 0 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2221 0 : const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse with Body
2222 0 : if( !(GetType() & nTmpType) && HasFixSize() )
2223 0 : return 0;
2224 :
2225 0 : SWRECTFN( this )
2226 0 : const SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2227 0 : const SwTwips nFrmPos = Frm().Pos().X();
2228 :
2229 0 : if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
2230 0 : nDist = LONG_MAX - nFrmHeight;
2231 :
2232 0 : SwTwips nMin = 0;
2233 0 : if ( GetUpper() && !IsCellFrm() )
2234 : {
2235 0 : SwFrm *pFrm = GetUpper()->Lower();
2236 0 : while( pFrm )
2237 0 : { nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2238 0 : pFrm = pFrm->GetNext();
2239 : }
2240 0 : nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin;
2241 0 : if ( nMin < 0 )
2242 0 : nMin = 0;
2243 : }
2244 :
2245 0 : SwRect aOldFrm( Frm() );
2246 0 : bool bMoveAccFrm = false;
2247 :
2248 0 : bool bChgPos = IsVertical() && !IsReverse();
2249 0 : if ( !bTst )
2250 : {
2251 0 : (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
2252 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2253 0 : if( bChgPos && !IsVertLR() )
2254 0 : Frm().Pos().X() -= nDist;
2255 0 : bMoveAccFrm = true;
2256 : }
2257 :
2258 0 : SwTwips nReal = nDist - nMin;
2259 0 : if ( nReal > 0 )
2260 : {
2261 0 : if ( GetUpper() )
2262 : { // AdjustNeighbourhood now only for the columns (but not in frames)
2263 0 : sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
2264 0 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2265 0 : : NA_GROW_SHRINK;
2266 0 : if( NA_ONLY_ADJUST == nAdjust )
2267 0 : nReal = AdjustNeighbourhood( nReal, bTst );
2268 : else
2269 : {
2270 0 : if( NA_ADJUST_GROW == nAdjust )
2271 0 : nReal += AdjustNeighbourhood( nReal, bTst );
2272 :
2273 0 : SwTwips nGrow = 0;
2274 0 : if( 0 < nReal )
2275 : {
2276 0 : SwFrm* pToGrow = GetUpper();
2277 : // NEW TABLES
2278 : // A cell with a row span of > 1 is allowed to grow the
2279 : // line containing the end of the row span if it is
2280 : // located in the same table frame:
2281 0 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2282 0 : if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2283 : {
2284 0 : SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2285 0 : if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
2286 0 : pToGrow = rEndCell.GetUpper();
2287 : else
2288 0 : pToGrow = 0;
2289 : }
2290 :
2291 0 : nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
2292 : }
2293 :
2294 0 : if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
2295 0 : nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
2296 :
2297 0 : if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
2298 : {
2299 : //Footnotes can replace their successor.
2300 0 : SwTwips nSpace = bTst ? 0 : -nDist;
2301 0 : const SwFrm *pFrm = GetUpper()->Lower();
2302 0 : do
2303 0 : { nSpace += (pFrm->Frm().*fnRect->fnGetHeight)();
2304 0 : pFrm = pFrm->GetNext();
2305 0 : } while ( pFrm != GetNext() );
2306 0 : nSpace = (GetUpper()->Prt().*fnRect->fnGetHeight)() -nSpace;
2307 0 : if ( nSpace < 0 )
2308 0 : nSpace = 0;
2309 0 : nSpace += nGrow;
2310 0 : if ( nReal > nSpace )
2311 0 : nReal = nSpace;
2312 0 : if ( nReal && !bTst )
2313 0 : ((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() );
2314 : }
2315 : else
2316 0 : nReal = nGrow;
2317 : }
2318 : }
2319 : else
2320 0 : nReal = 0;
2321 :
2322 0 : nReal += nMin;
2323 : }
2324 : else
2325 0 : nReal = nDist;
2326 :
2327 0 : if ( !bTst )
2328 : {
2329 0 : if( nReal != nDist &&
2330 : // NEW TABLES
2331 0 : ( !IsCellFrm() || static_cast<SwCellFrm*>(this)->GetLayoutRowSpan() > 1 ) )
2332 : {
2333 0 : (Frm().*fnRect->fnSetHeight)( nFrmHeight + nReal );
2334 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2335 0 : if( bChgPos && !IsVertLR() )
2336 0 : Frm().Pos().X() = nFrmPos - nReal;
2337 0 : bMoveAccFrm = true;
2338 : }
2339 :
2340 0 : if ( nReal )
2341 : {
2342 0 : SwPageFrm *pPage = FindPageFrm();
2343 0 : if ( GetNext() )
2344 : {
2345 0 : GetNext()->_InvalidatePos();
2346 0 : if ( GetNext()->IsCntntFrm() )
2347 0 : GetNext()->InvalidatePage( pPage );
2348 : }
2349 0 : if ( !IsPageBodyFrm() )
2350 : {
2351 0 : _InvalidateAll();
2352 0 : InvalidatePage( pPage );
2353 : }
2354 0 : if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2355 0 : NotifyLowerObjs();
2356 :
2357 0 : if( IsCellFrm() )
2358 0 : InvaPercentLowers( nReal );
2359 :
2360 0 : const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2361 0 : if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2362 0 : SetCompletePaint();
2363 : }
2364 : }
2365 :
2366 0 : if( bMoveAccFrm && IsAccessibleFrm() )
2367 : {
2368 0 : SwRootFrm *pRootFrm = getRootFrm();
2369 0 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2370 0 : pRootFrm->GetCurrShell() )
2371 : {
2372 0 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2373 : }
2374 : }
2375 0 : return nReal;
2376 : }
2377 :
2378 0 : SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2379 : {
2380 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
2381 0 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2382 0 : const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
2383 0 : if( !(GetType() & nTmpType) && HasFixSize() )
2384 0 : return 0;
2385 :
2386 : OSL_ENSURE( nDist >= 0, "nDist < 0" );
2387 0 : SWRECTFN( this )
2388 0 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2389 0 : if ( nDist > nFrmHeight )
2390 0 : nDist = nFrmHeight;
2391 :
2392 0 : SwTwips nMin = 0;
2393 0 : bool bChgPos = IsVertical() && !IsReverse();
2394 0 : if ( Lower() )
2395 : {
2396 0 : if( !Lower()->IsNeighbourFrm() )
2397 0 : { const SwFrm *pFrm = Lower();
2398 0 : const long nTmp = (Prt().*fnRect->fnGetHeight)();
2399 0 : while( pFrm && nMin < nTmp )
2400 0 : { nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2401 0 : pFrm = pFrm->GetNext();
2402 : }
2403 : }
2404 : }
2405 0 : SwTwips nReal = nDist;
2406 0 : SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin;
2407 0 : if( nReal > nMinDiff )
2408 0 : nReal = nMinDiff;
2409 0 : if( nReal <= 0 )
2410 0 : return nDist;
2411 :
2412 0 : SwRect aOldFrm( Frm() );
2413 0 : bool bMoveAccFrm = false;
2414 :
2415 0 : SwTwips nRealDist = nReal;
2416 0 : if ( !bTst )
2417 : {
2418 0 : (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal );
2419 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2420 0 : if( bChgPos && !IsVertLR() )
2421 0 : Frm().Pos().X() += nReal;
2422 0 : bMoveAccFrm = true;
2423 : }
2424 :
2425 0 : sal_uInt8 nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
2426 0 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2427 0 : : NA_GROW_SHRINK;
2428 :
2429 : // AdjustNeighbourhood also in columns (but not in frames)
2430 0 : if( NA_ONLY_ADJUST == nAdjust )
2431 : {
2432 0 : if ( IsPageBodyFrm() && !bBrowse )
2433 0 : nReal = nDist;
2434 : else
2435 0 : { nReal = AdjustNeighbourhood( -nReal, bTst );
2436 0 : nReal *= -1;
2437 0 : if ( !bTst && IsBodyFrm() && nReal < nRealDist )
2438 : {
2439 0 : (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2440 0 : + nRealDist - nReal );
2441 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2442 0 : if( bChgPos && !IsVertLR() )
2443 0 : Frm().Pos().X() += nRealDist - nReal;
2444 : OSL_ENSURE( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2445 : }
2446 : }
2447 : }
2448 0 : else if( IsColumnFrm() || IsColBodyFrm() )
2449 : {
2450 0 : SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
2451 0 : if ( nTmp != nReal )
2452 : {
2453 0 : (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2454 0 : + nReal - nTmp );
2455 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2456 0 : if( bChgPos && !IsVertLR() )
2457 0 : Frm().Pos().X() += nTmp - nReal;
2458 : OSL_ENSURE( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2459 0 : nReal = nTmp;
2460 : }
2461 : }
2462 : else
2463 : {
2464 0 : SwTwips nShrink = nReal;
2465 0 : SwFrm* pToShrink = GetUpper();
2466 0 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2467 : // NEW TABLES
2468 0 : if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2469 : {
2470 0 : SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2471 0 : pToShrink = rEndCell.GetUpper();
2472 : }
2473 :
2474 0 : nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
2475 0 : if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
2476 0 : && nReal < nShrink )
2477 0 : AdjustNeighbourhood( nReal - nShrink );
2478 : }
2479 :
2480 0 : if( bMoveAccFrm && IsAccessibleFrm() )
2481 : {
2482 0 : SwRootFrm *pRootFrm = getRootFrm();
2483 0 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2484 0 : pRootFrm->GetCurrShell() )
2485 : {
2486 0 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2487 : }
2488 : }
2489 0 : if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
2490 : {
2491 0 : SwPageFrm *pPage = FindPageFrm();
2492 0 : if ( GetNext() )
2493 : {
2494 0 : GetNext()->_InvalidatePos();
2495 0 : if ( GetNext()->IsCntntFrm() )
2496 0 : GetNext()->InvalidatePage( pPage );
2497 0 : if ( IsTabFrm() )
2498 0 : ((SwTabFrm*)this)->SetComplete();
2499 : }
2500 : else
2501 0 : { if ( IsRetoucheFrm() )
2502 0 : SetRetouche();
2503 0 : if ( IsTabFrm() )
2504 : {
2505 0 : if( IsTabFrm() )
2506 0 : ((SwTabFrm*)this)->SetComplete();
2507 0 : if ( Lower() ) // Can also be in the Join and be empty!
2508 0 : InvalidateNextPos();
2509 : }
2510 : }
2511 0 : if ( !IsBodyFrm() )
2512 : {
2513 0 : _InvalidateAll();
2514 0 : InvalidatePage( pPage );
2515 0 : bool bCompletePaint = true;
2516 0 : const SwFrmFmt* pFmt = GetFmt();
2517 0 : if (pFmt)
2518 : {
2519 0 : const SvxGraphicPosition ePos = pFmt->GetBackground().GetGraphicPos();
2520 0 : if ( GPOS_NONE == ePos || GPOS_TILED == ePos )
2521 0 : bCompletePaint = false;
2522 : }
2523 0 : if (bCompletePaint)
2524 0 : SetCompletePaint();
2525 : }
2526 :
2527 0 : if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2528 0 : NotifyLowerObjs();
2529 :
2530 0 : if( IsCellFrm() )
2531 0 : InvaPercentLowers( nReal );
2532 :
2533 : SwCntntFrm *pCnt;
2534 0 : if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
2535 0 : ( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
2536 0 : ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) &&
2537 : 0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) )
2538 : {
2539 0 : if ( pCnt->IsFollow() )
2540 : { // If we are in an other column/page than the frame with the
2541 : // reference, we don't need to invalidate its master.
2542 0 : SwFrm *pTmp = pCnt->FindFtnBossFrm(sal_True) == FindFtnBossFrm(sal_True)
2543 0 : ? pCnt->FindMaster()->GetFrm() : pCnt;
2544 0 : pTmp->Prepare( PREP_ADJUST_FRM );
2545 0 : pTmp->InvalidateSize();
2546 : }
2547 : else
2548 0 : pCnt->InvalidatePos();
2549 : }
2550 : }
2551 0 : return nReal;
2552 : }
2553 :
2554 : /**
2555 : * Changes the size of the directly subsidiary Frm's that have a fixed size, proportionally to the
2556 : * size change of the PrtArea of the Frm's.
2557 : *
2558 : * The variable Frms are also proportionally adapted; they will grow/shrink again by themselves.
2559 : */
2560 0 : void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
2561 : {
2562 : // no change of lower properties for root frame or if no lower exists.
2563 0 : if ( IsRootFrm() || !Lower() )
2564 0 : return;
2565 :
2566 : // declare and init <SwFrm* pLowerFrm> with first lower
2567 0 : SwFrm *pLowerFrm = Lower();
2568 :
2569 : // declare and init const booleans <bHeightChgd> and <bWidthChg>
2570 0 : const bool bHeightChgd = rOldSize.Height() != Prt().Height();
2571 0 : const bool bWidthChgd = rOldSize.Width() != Prt().Width();
2572 :
2573 : // declare and init variables <bVert>, <bRev> and <fnRect>
2574 0 : SWRECTFN( this )
2575 :
2576 : // This shortcut basically tries to handle only lower frames that
2577 : // are affected by the size change. Otherwise much more lower frames
2578 : // are invalidated.
2579 0 : if ( !( bVert ? bHeightChgd : bWidthChgd ) &&
2580 0 : ! Lower()->IsColumnFrm() &&
2581 0 : ( ( IsBodyFrm() && IsInDocBody() && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) ) ||
2582 : // #i10826# Section frames without columns should not
2583 : // invalidate all lowers!
2584 0 : IsSctFrm() ) )
2585 : {
2586 : // Determine page frame the body frame resp. the section frame belongs to.
2587 0 : SwPageFrm *pPage = FindPageFrm();
2588 : // Determine last lower by traveling through them using <GetNext()>.
2589 : // During travel check each section frame, if it will be sized to
2590 : // maximum. If Yes, invalidate size of section frame and set
2591 : // corresponding flags at the page.
2592 : do
2593 : {
2594 0 : if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() )
2595 : {
2596 0 : pLowerFrm->_InvalidateSize();
2597 0 : pLowerFrm->InvalidatePage( pPage );
2598 : }
2599 0 : if( pLowerFrm->GetNext() )
2600 0 : pLowerFrm = pLowerFrm->GetNext();
2601 : else
2602 0 : break;
2603 : } while( true );
2604 : // If found last lower is a section frame containing no section
2605 : // (section frame isn't valid and will be deleted in the future),
2606 : // travel backwards.
2607 0 : while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() &&
2608 0 : pLowerFrm->GetPrev() )
2609 0 : pLowerFrm = pLowerFrm->GetPrev();
2610 : // If found last lower is a section frame, set <pLowerFrm> to its last
2611 : // content, if the section frame is valid and is not sized to maximum.
2612 : // Otherwise set <pLowerFrm> to NULL - In this case body frame only
2613 : // contains invalid section frames.
2614 0 : if( pLowerFrm->IsSctFrm() )
2615 0 : pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() &&
2616 0 : !((SwSectionFrm*)pLowerFrm)->ToMaximize( sal_False ) ?
2617 0 : ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL;
2618 :
2619 : // continue with found last lower, probably the last content of a section
2620 0 : if ( pLowerFrm )
2621 : {
2622 : // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table
2623 : // frame and continue.
2624 0 : if ( pLowerFrm->IsInTab() )
2625 : {
2626 : // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to
2627 : // its table frame - check, if the table frame is also a lower
2628 : // of the body frame, in order to assure that <pLowerFrm> is not
2629 : // set to a frame, which is an *upper* of the body frame.
2630 0 : SwFrm* pTableFrm = pLowerFrm->FindTabFrm();
2631 0 : if ( IsAnLower( pTableFrm ) )
2632 : {
2633 0 : pLowerFrm = pTableFrm;
2634 : }
2635 : }
2636 : // Check, if variable size of body frame resp. section frame has grown
2637 : // OD 28.10.2002 #97265# - correct check, if variable size has grown.
2638 0 : SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height();
2639 0 : if( nOldHeight < (Prt().*fnRect->fnGetHeight)() )
2640 : {
2641 : // If variable size of body|section frame has grown, only found
2642 : // last lower and the position of the its next have to be invalidated.
2643 0 : pLowerFrm->_InvalidateAll();
2644 0 : pLowerFrm->InvalidatePage( pPage );
2645 0 : if( !pLowerFrm->IsFlowFrm() ||
2646 0 : !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() )
2647 0 : pLowerFrm->InvalidateNextPos( sal_True );
2648 0 : if ( pLowerFrm->IsTxtFrm() )
2649 0 : ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2650 : }
2651 : else
2652 : {
2653 : // variable size of body|section frame has shrinked. Thus,
2654 : // invalidate all lowers not matching the new body|section size
2655 : // and the dedicated new last lower.
2656 0 : if( bVert )
2657 : {
2658 0 : SwTwips nBot = Frm().Left() + Prt().Left();
2659 0 : while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot )
2660 : {
2661 0 : pLowerFrm->_InvalidateAll();
2662 0 : pLowerFrm->InvalidatePage( pPage );
2663 0 : pLowerFrm = pLowerFrm->GetPrev();
2664 : }
2665 : }
2666 : else
2667 : {
2668 0 : SwTwips nBot = Frm().Top() + Prt().Bottom();
2669 0 : while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot )
2670 : {
2671 0 : pLowerFrm->_InvalidateAll();
2672 0 : pLowerFrm->InvalidatePage( pPage );
2673 0 : pLowerFrm = pLowerFrm->GetPrev();
2674 : }
2675 : }
2676 0 : if ( pLowerFrm )
2677 : {
2678 0 : pLowerFrm->_InvalidateSize();
2679 0 : pLowerFrm->InvalidatePage( pPage );
2680 0 : if ( pLowerFrm->IsTxtFrm() )
2681 0 : ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2682 : }
2683 : }
2684 : // #i41694# - improvement by removing duplicates
2685 0 : if ( pLowerFrm )
2686 : {
2687 0 : if ( pLowerFrm->IsInSct() )
2688 : {
2689 : // #i41694# - follow-up of issue #i10826#
2690 : // No invalidation of section frame, if it's the this.
2691 0 : SwFrm* pSectFrm = pLowerFrm->FindSctFrm();
2692 0 : if( pSectFrm != this && IsAnLower( pSectFrm ) )
2693 : {
2694 0 : pSectFrm->_InvalidateSize();
2695 0 : pSectFrm->InvalidatePage( pPage );
2696 : }
2697 : }
2698 : }
2699 : }
2700 0 : return;
2701 : } // end of { special case }
2702 :
2703 : // Invalidate page for content only once.
2704 0 : bool bInvaPageForCntnt = true;
2705 :
2706 : // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
2707 : // adjustment, if fixed/variable size has changed.
2708 : bool bFixChgd, bVarChgd;
2709 0 : if( bVert == pLowerFrm->IsNeighbourFrm() )
2710 : {
2711 0 : bFixChgd = bWidthChgd;
2712 0 : bVarChgd = bHeightChgd;
2713 : }
2714 : else
2715 : {
2716 0 : bFixChgd = bHeightChgd;
2717 0 : bVarChgd = bWidthChgd;
2718 : }
2719 :
2720 : // Declare const unsigned short <nFixWidth> and init it this frame types
2721 : // which has fixed width in vertical respectively horizontal layout.
2722 : // In vertical layout these are neighbour frames (cell and column frames),
2723 : // header frames and footer frames.
2724 : // In horizontal layout these are all frames, which aren't neighbour frames.
2725 : const sal_uInt16 nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
2726 0 : : ~FRM_NEIGHBOUR;
2727 :
2728 : // Declare const unsigned short <nFixHeight> and init it this frame types
2729 : // which has fixed height in vertical respectively horizontal layout.
2730 : // In vertical layout these are all frames, which aren't neighbour frames,
2731 : // header frames, footer frames, body frames or foot note container frames.
2732 : // In horizontal layout these are neighbour frames.
2733 : const sal_uInt16 nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
2734 0 : : FRM_NEIGHBOUR;
2735 :
2736 : // Travel through all lowers using <GetNext()>
2737 0 : while ( pLowerFrm )
2738 : {
2739 0 : if ( pLowerFrm->IsTxtFrm() )
2740 : {
2741 : // Text frames will only be invalidated - prepare invalidation
2742 0 : if ( bFixChgd )
2743 0 : static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG );
2744 0 : if ( bVarChgd )
2745 0 : static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2746 : }
2747 : else
2748 : {
2749 : // If lower isn't a table, row, cell or section frame, adjust its
2750 : // frame size.
2751 0 : const sal_uInt16 nLowerType = pLowerFrm->GetType();
2752 0 : if ( !(nLowerType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
2753 : {
2754 0 : if ( bWidthChgd )
2755 : {
2756 0 : if( nLowerType & nFixWidth )
2757 : {
2758 : // Considering previous conditions:
2759 : // In vertical layout set width of column, header and
2760 : // footer frames to its upper width.
2761 : // In horizontal layout set width of header, footer,
2762 : // foot note container, foot note, body and no-text
2763 : // frames to its upper width.
2764 0 : pLowerFrm->Frm().Width( Prt().Width() );
2765 : }
2766 0 : else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() )
2767 : {
2768 : // Adjust frame width proportional, if lower isn't a
2769 : // foot note frame and condition <nLowerType & nFixWidth>
2770 : // isn't true.
2771 : // Considering previous conditions:
2772 : // In vertical layout these are foot note container,
2773 : // body and no-text frames.
2774 : // In horizontal layout these are column and no-text frames.
2775 : // OD 24.10.2002 #97265# - <double> calculation
2776 : // Perform <double> calculation of new width, if
2777 : // one of the coefficients is greater than 50000
2778 : SwTwips nNewWidth;
2779 0 : if ( (pLowerFrm->Frm().Width() > 50000) ||
2780 0 : (Prt().Width() > 50000) )
2781 : {
2782 : double nNewWidthTmp =
2783 0 : ( double(pLowerFrm->Frm().Width())
2784 0 : * double(Prt().Width()) )
2785 0 : / double(rOldSize.Width());
2786 0 : nNewWidth = SwTwips(nNewWidthTmp);
2787 : }
2788 : else
2789 : {
2790 : nNewWidth =
2791 0 : (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width();
2792 : }
2793 0 : pLowerFrm->Frm().Width( nNewWidth );
2794 : }
2795 : }
2796 0 : if ( bHeightChgd )
2797 : {
2798 0 : if( nLowerType & nFixHeight )
2799 : {
2800 : // Considering previous conditions:
2801 : // In vertical layout set height of foot note and
2802 : // no-text frames to its upper height.
2803 : // In horizontal layout set height of column frames
2804 : // to its upper height.
2805 0 : pLowerFrm->Frm().Height( Prt().Height() );
2806 : }
2807 : // OD 01.10.2002 #102211#
2808 : // add conditions <!pLowerFrm->IsHeaderFrm()> and
2809 : // <!pLowerFrm->IsFooterFrm()> in order to avoid that
2810 : // the <Grow> of header or footer are overwritten.
2811 : // NOTE: Height of header/footer frame is determined by contents.
2812 0 : else if ( rOldSize.Height() &&
2813 0 : !pLowerFrm->IsFtnFrm() &&
2814 0 : !pLowerFrm->IsHeaderFrm() &&
2815 0 : !pLowerFrm->IsFooterFrm()
2816 : )
2817 : {
2818 : // Adjust frame height proportional, if lower isn't a
2819 : // foot note, a header or a footer frame and
2820 : // condition <nLowerType & nFixHeight> isn't true.
2821 : // Considering previous conditions:
2822 : // In vertical layout these are column, foot note container,
2823 : // body and no-text frames.
2824 : // In horizontal layout these are column, foot note
2825 : // container, body and no-text frames.
2826 :
2827 : // OD 29.10.2002 #97265# - special case for page lowers
2828 : // The page lowers that have to be adjusted on page height
2829 : // change are the body frame and the foot note container
2830 : // frame.
2831 : // In vertical layout the height of both is directly
2832 : // adjusted to the page height change.
2833 : // In horizontal layout the height of the body frame is
2834 : // directly adjsuted to the page height change and the
2835 : // foot note frame height isn't touched, because its
2836 : // determined by its content.
2837 : // OD 31.03.2003 #108446# - apply special case for page
2838 : // lowers - see description above - also for section columns.
2839 0 : if ( IsPageFrm() ||
2840 0 : ( IsColumnFrm() && IsInSct() )
2841 : )
2842 : {
2843 : OSL_ENSURE( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(),
2844 : "ChgLowersProp - only for body or foot note container" );
2845 0 : if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() )
2846 : {
2847 0 : if ( IsVertical() || pLowerFrm->IsBodyFrm() )
2848 : {
2849 : SwTwips nNewHeight =
2850 0 : pLowerFrm->Frm().Height() +
2851 0 : ( Prt().Height() - rOldSize.Height() );
2852 0 : if ( nNewHeight < 0)
2853 : {
2854 : // OD 01.04.2003 #108446# - adjust assertion condition and text
2855 : OSL_ENSURE( !( IsPageFrm() &&
2856 : (pLowerFrm->Frm().Height()>0) &&
2857 : (pLowerFrm->IsValid()) ),
2858 : "ChgLowersProg - negative height for lower.");
2859 0 : nNewHeight = 0;
2860 : }
2861 0 : pLowerFrm->Frm().Height( nNewHeight );
2862 : }
2863 : }
2864 : }
2865 : else
2866 : {
2867 : SwTwips nNewHeight;
2868 : // OD 24.10.2002 #97265# - <double> calculation
2869 : // Perform <double> calculation of new height, if
2870 : // one of the coefficients is greater than 50000
2871 0 : if ( (pLowerFrm->Frm().Height() > 50000) ||
2872 0 : (Prt().Height() > 50000) )
2873 : {
2874 : double nNewHeightTmp =
2875 0 : ( double(pLowerFrm->Frm().Height())
2876 0 : * double(Prt().Height()) )
2877 0 : / double(rOldSize.Height());
2878 0 : nNewHeight = SwTwips(nNewHeightTmp);
2879 : }
2880 : else
2881 : {
2882 0 : nNewHeight = ( pLowerFrm->Frm().Height()
2883 0 : * Prt().Height() ) / rOldSize.Height();
2884 : }
2885 0 : if( !pLowerFrm->GetNext() )
2886 : {
2887 0 : SwTwips nSum = Prt().Height();
2888 0 : SwFrm* pTmp = Lower();
2889 0 : while( pTmp->GetNext() )
2890 : {
2891 0 : if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() )
2892 0 : nSum -= pTmp->Frm().Height();
2893 0 : pTmp = pTmp->GetNext();
2894 : }
2895 0 : if( nSum - nNewHeight == 1 &&
2896 0 : nSum == pLowerFrm->Frm().Height() )
2897 0 : nNewHeight = nSum;
2898 : }
2899 0 : pLowerFrm->Frm().Height( nNewHeight );
2900 : }
2901 : }
2902 : }
2903 : }
2904 : } // end of else { NOT text frame }
2905 :
2906 0 : pLowerFrm->_InvalidateAll();
2907 0 : if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() )
2908 : {
2909 0 : pLowerFrm->InvalidatePage();
2910 0 : bInvaPageForCntnt = false;
2911 : }
2912 :
2913 0 : if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() )
2914 : {
2915 : //If a growth took place and the subordinate elements can retouch
2916 : //itself (currently Tabs, Sections and Cntnt) we trigger it.
2917 0 : if ( rOldSize.Height() < Prt().SSize().Height() ||
2918 0 : rOldSize.Width() < Prt().SSize().Width() )
2919 0 : pLowerFrm->SetRetouche();
2920 : }
2921 0 : pLowerFrm = pLowerFrm->GetNext();
2922 : }
2923 :
2924 : // Finally adjust the columns if width is set to auto
2925 : // Possible optimization: execute this code earlier in this function and
2926 : // return???
2927 0 : if ( ( (bVert && bHeightChgd) || (! bVert && bWidthChgd) ) &&
2928 0 : Lower()->IsColumnFrm() )
2929 : {
2930 : // get column attribute
2931 0 : const SwFmtCol* pColAttr = NULL;
2932 0 : if ( IsPageBodyFrm() )
2933 : {
2934 : OSL_ENSURE( GetUpper()->IsPageFrm(), "Upper is not page frame" );
2935 0 : pColAttr = &GetUpper()->GetFmt()->GetCol();
2936 : }
2937 : else
2938 : {
2939 : OSL_ENSURE( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" );
2940 0 : pColAttr = &GetFmt()->GetCol();
2941 : }
2942 :
2943 0 : if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
2944 0 : AdjustColumns( pColAttr, sal_False );
2945 : }
2946 : }
2947 :
2948 : /** "Formats" the Frame; Frm and PrtArea.
2949 : *
2950 : * The Fixsize is not set here.
2951 : */
2952 0 : void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
2953 : {
2954 : OSL_ENSURE( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );
2955 :
2956 0 : if ( mbValidPrtArea && mbValidSize )
2957 0 : return;
2958 :
2959 0 : const sal_uInt16 nLeft = (sal_uInt16)pAttrs->CalcLeft( this );
2960 0 : const sal_uInt16 nUpper = pAttrs->CalcTop();
2961 :
2962 0 : const sal_uInt16 nRight = (sal_uInt16)((SwBorderAttrs*)pAttrs)->CalcRight( this );
2963 0 : const sal_uInt16 nLower = pAttrs->CalcBottom();
2964 0 : bool bVert = IsVertical() && !IsPageFrm();
2965 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2966 0 : SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
2967 0 : if ( !mbValidPrtArea )
2968 : {
2969 0 : mbValidPrtArea = sal_True;
2970 0 : (this->*fnRect->fnSetXMargins)( nLeft, nRight );
2971 0 : (this->*fnRect->fnSetYMargins)( nUpper, nLower );
2972 : }
2973 :
2974 0 : if ( !mbValidSize )
2975 : {
2976 0 : if ( !HasFixSize() )
2977 : {
2978 0 : const SwTwips nBorder = nUpper + nLower;
2979 0 : const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
2980 0 : SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
2981 0 : do
2982 0 : { mbValidSize = sal_True;
2983 :
2984 : //The size in VarSize is calculated using the content plus the
2985 : // borders.
2986 0 : SwTwips nRemaining = 0;
2987 0 : SwFrm *pFrm = Lower();
2988 0 : while ( pFrm )
2989 0 : { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
2990 0 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
2991 : // This TxtFrm would like to be a bit bigger
2992 0 : nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
2993 0 : - (pFrm->Prt().*fnRect->fnGetHeight)();
2994 0 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
2995 0 : nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
2996 0 : pFrm = pFrm->GetNext();
2997 : }
2998 0 : nRemaining += nBorder;
2999 0 : nRemaining = std::max( nRemaining, nMinHeight );
3000 0 : const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)();
3001 0 : const long nOldLeft = (Frm().*fnRect->fnGetLeft)();
3002 0 : const long nOldTop = (Frm().*fnRect->fnGetTop)();
3003 0 : if ( nDiff )
3004 : {
3005 0 : if ( nDiff > 0 )
3006 0 : Grow( nDiff );
3007 : else
3008 0 : Shrink( -nDiff );
3009 : //Updates the positions using the fast channel.
3010 0 : MakePos();
3011 : }
3012 : //Don't exceed the bottom edge of the Upper.
3013 0 : if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() )
3014 : {
3015 0 : const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
3016 0 : if( (this->*fnRect->fnSetLimit)( nLimit ) &&
3017 0 : nOldLeft == (Frm().*fnRect->fnGetLeft)() &&
3018 0 : nOldTop == (Frm().*fnRect->fnGetTop)() )
3019 0 : mbValidSize = mbValidPrtArea = sal_True;
3020 : }
3021 0 : } while ( !mbValidSize );
3022 : }
3023 0 : else if ( GetType() & 0x0018 )
3024 : {
3025 0 : do
3026 0 : { if ( Frm().Height() != pAttrs->GetSize().Height() )
3027 0 : ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
3028 0 : mbValidSize = sal_True;
3029 0 : MakePos();
3030 0 : } while ( !mbValidSize );
3031 : }
3032 : else
3033 0 : mbValidSize = sal_True;
3034 : }
3035 : }
3036 :
3037 0 : static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff )
3038 : {
3039 : OSL_ENSURE( pFrm->GetDrawObjs(), "Can't find any Objects" );
3040 0 : for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
3041 : {
3042 0 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3043 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3044 : {
3045 0 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3046 0 : const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
3047 0 : if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3048 : {
3049 0 : bool bNotify = true;
3050 : // If we've a fly with more than 90% relative height...
3051 0 : if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrm() &&
3052 0 : rSz.GetHeightPercent() != 0xFF && nDiff )
3053 : {
3054 0 : const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchorFrm():
3055 0 : pFly->GetAnchorFrm()->GetUpper();
3056 : // ... and we have already more than 90% height and we
3057 : // not allow the text to go through...
3058 : // then a notifycation could cause an endless loop, e.g.
3059 : // 100% height and no text wrap inside a cell of a table.
3060 0 : if( pFly->Frm().Height()*10 >
3061 0 : ( nDiff + pRel->Prt().Height() )*9 &&
3062 0 : pFly->GetFmt()->GetSurround().GetSurround() !=
3063 : SURROUND_THROUGHT )
3064 0 : bNotify = false;
3065 : }
3066 0 : if( bNotify )
3067 0 : pFly->InvalidateSize();
3068 : }
3069 : }
3070 : }
3071 0 : }
3072 :
3073 0 : void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff )
3074 : {
3075 0 : if ( GetDrawObjs() )
3076 0 : ::InvaPercentFlys( this, nDiff );
3077 :
3078 0 : SwFrm *pFrm = ContainsCntnt();
3079 0 : if ( pFrm )
3080 0 : do
3081 : {
3082 0 : if ( pFrm->IsInTab() && !IsTabFrm() )
3083 : {
3084 0 : SwFrm *pTmp = pFrm->FindTabFrm();
3085 : OSL_ENSURE( pTmp, "Where's my TabFrm?" );
3086 0 : if( IsAnLower( pTmp ) )
3087 0 : pFrm = pTmp;
3088 : }
3089 :
3090 0 : if ( pFrm->IsTabFrm() )
3091 : {
3092 0 : const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
3093 0 : if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3094 0 : pFrm->InvalidatePrt();
3095 : }
3096 0 : else if ( pFrm->GetDrawObjs() )
3097 0 : ::InvaPercentFlys( pFrm, nDiff );
3098 0 : pFrm = pFrm->FindNextCnt();
3099 0 : } while ( pFrm && IsAnLower( pFrm ) ) ;
3100 0 : }
3101 :
3102 0 : long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, sal_Bool ) const
3103 : {
3104 0 : long nRet = rSz.GetWidth(),
3105 0 : nPercent = rSz.GetWidthPercent();
3106 :
3107 0 : if ( nPercent )
3108 : {
3109 0 : const SwFrm *pRel = GetUpper();
3110 0 : long nRel = LONG_MAX;
3111 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
3112 0 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
3113 0 : if( pRel->IsPageBodyFrm() && pSh && bBrowseMode && pSh->VisArea().Width() )
3114 : {
3115 0 : nRel = pSh->GetBrowseWidth();
3116 0 : long nDiff = nRel - pRel->Prt().Width();
3117 0 : if ( nDiff > 0 )
3118 0 : nRel -= nDiff;
3119 : }
3120 0 : nRel = std::min( nRel, pRel->Prt().Width() );
3121 0 : nRet = nRel * nPercent / 100;
3122 : }
3123 0 : return nRet;
3124 : }
3125 :
3126 : // Local helpers for SwLayoutFrm::FormatWidthCols()
3127 :
3128 0 : static long lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
3129 : {
3130 0 : long nDiff = 0, nFirstDiff = 0;
3131 0 : SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
3132 : OSL_ENSURE( pCol, "Where's the columnframe?" );
3133 0 : SwFrm *pFrm = pCol->Lower();
3134 0 : do
3135 : {
3136 0 : if( pFrm && pFrm->IsBodyFrm() )
3137 0 : pFrm = ((SwBodyFrm*)pFrm)->Lower();
3138 0 : if ( pFrm && pFrm->IsTxtFrm() )
3139 : {
3140 0 : const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
3141 0 : if ( nTmp != USHRT_MAX )
3142 : {
3143 0 : if ( pCol == pLayFrm->Lower() )
3144 0 : nFirstDiff = nTmp;
3145 : else
3146 0 : nDiff = nDiff ? std::min( nDiff, nTmp ) : nTmp;
3147 : }
3148 : }
3149 : //Skip empty columns!
3150 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3151 0 : while ( pCol && 0 == (pFrm = pCol->Lower()) )
3152 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3153 :
3154 0 : } while ( pFrm && pCol );
3155 :
3156 0 : return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
3157 : }
3158 :
3159 0 : static bool lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
3160 : {
3161 0 : SwFrm *pFrm = pLay->ContainsCntnt();
3162 0 : while ( pFrm )
3163 : {
3164 0 : if ( pFrm->IsInTab() )
3165 0 : pFrm = pFrm->FindTabFrm();
3166 :
3167 0 : if ( pFrm->GetDrawObjs() )
3168 : {
3169 0 : sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
3170 0 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
3171 : {
3172 0 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3173 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3174 : {
3175 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3176 0 : if ( pFly->IsHeightClipped() &&
3177 0 : ( !pFly->IsFlyFreeFrm() || pFly->GetPageFrm() ) )
3178 0 : return true;
3179 : }
3180 : }
3181 : }
3182 0 : pFrm = pFrm->FindNextCnt();
3183 : }
3184 0 : return false;
3185 : }
3186 :
3187 0 : void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
3188 : const SwTwips nBorder, const SwTwips nMinHeight )
3189 : {
3190 : //If there are columns involved, the size is adjusted using the last column.
3191 : //1. Format content.
3192 : //2. Calculate height of the last column: if it's too big, the Fly has to
3193 : // grow. The amount by which the Fly grows is not the amount of the
3194 : // overhang because we have to act on the assumption that some text flows
3195 : // back which will generate some more space.
3196 : // The amount which we grow by equals the overhang
3197 : // divided by the amount of columns or the overhang itself if it's smaller
3198 : // than the amount of columns.
3199 : //3. Go back to 1. until everything is stable.
3200 :
3201 0 : const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
3202 0 : const sal_uInt16 nNumCols = rCol.GetNumCols();
3203 :
3204 0 : bool bEnd = false;
3205 0 : bool bBackLock = false;
3206 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
3207 0 : SwViewImp *pImp = pSh ? pSh->Imp() : 0;
3208 : {
3209 : // Underlying algorithm
3210 : // We try to find the optimal height for the column.
3211 : // nMinimum starts with the passed minimum height and is then remembered
3212 : // as the maximum height on which column content still juts out of a
3213 : // column.
3214 : // nMaximum starts with LONG_MAX and is then remembered as the minimum
3215 : // width on which the content fitted.
3216 : // In column based sections nMaximum starts at the maximum value which
3217 : // the surrounding defines, this can certainly be a value on which
3218 : // content still juts out.
3219 : // The columns are formatted. If content still juts out, nMinimum is
3220 : // adjusted accordingly, then we grow, at least by uMinDiff but not
3221 : // over a certain nMaximum. If no content juts out but there is still
3222 : // some space left in the column, shrinking is done accordingly, at
3223 : // least by nMindIff but not below the nMinimum.
3224 : // Cancel as soon as no content juts out and the difference from minimum
3225 : // to maximum is less than MinDiff or the maximum which was defined by
3226 : // the surrounding is reached even if some content still juts out.
3227 :
3228 : // Criticism of this implementation
3229 : // 1. Theoretically situations are possible in which the content fits in
3230 : // a lower height but not in a higher height. To ensure that the code
3231 : // handles such situations the code contains a few checks concerning
3232 : // minimum and maximum which probably are never triggered.
3233 : // 2. We use the same nMinDiff for shrinking and growing, but nMinDiff
3234 : // is more or less the smallest first line height and doesn't seem ideal
3235 : // as minimum value.
3236 :
3237 0 : long nMinimum = nMinHeight;
3238 : long nMaximum;
3239 0 : sal_Bool bNoBalance = sal_False;
3240 0 : SWRECTFN( this )
3241 0 : if( IsSctFrm() )
3242 : {
3243 0 : nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder +
3244 0 : (Frm().*fnRect->fnBottomDist)(
3245 0 : (GetUpper()->*fnRect->fnGetPrtBottom)() );
3246 0 : nMaximum += GetUpper()->Grow( LONG_MAX, sal_True );
3247 0 : if( nMaximum < nMinimum )
3248 : {
3249 0 : if( nMaximum < 0 )
3250 0 : nMinimum = nMaximum = 0;
3251 : else
3252 0 : nMinimum = nMaximum;
3253 : }
3254 0 : if( nMaximum > BROWSE_HEIGHT )
3255 0 : nMaximum = BROWSE_HEIGHT;
3256 :
3257 0 : bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()->
3258 0 : GetBalancedColumns().GetValue();
3259 0 : SwFrm* pAny = ContainsAny();
3260 0 : if( bNoBalance ||
3261 0 : ( !(Frm().*fnRect->fnGetHeight)() && pAny ) )
3262 : {
3263 0 : long nTop = (this->*fnRect->fnGetTopMargin)();
3264 : // #i23129# - correction
3265 : // to the calculated maximum height.
3266 0 : (Frm().*fnRect->fnAddBottom)( nMaximum -
3267 0 : (Frm().*fnRect->fnGetHeight)() );
3268 0 : if( nTop > nMaximum )
3269 0 : nTop = nMaximum;
3270 0 : (this->*fnRect->fnSetYMargins)( nTop, 0 );
3271 : }
3272 0 : if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() )
3273 : {
3274 0 : SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont();
3275 0 : if( pFtnCont )
3276 : {
3277 0 : SwFrm* pFtnAny = pFtnCont->ContainsAny();
3278 0 : if( pFtnAny && pFtnAny->IsValid() )
3279 : {
3280 0 : bBackLock = true;
3281 0 : ((SwSectionFrm*)this)->SetFtnLock( true );
3282 : }
3283 : }
3284 : }
3285 : }
3286 : else
3287 0 : nMaximum = LONG_MAX;
3288 :
3289 : // #i3317# - reset temporarly consideration
3290 : // of wrapping style influence
3291 0 : SwPageFrm* pPageFrm = FindPageFrm();
3292 0 : SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
3293 0 : if ( pObjs )
3294 : {
3295 0 : sal_uInt32 i = 0;
3296 0 : for ( i = 0; i < pObjs->Count(); ++i )
3297 : {
3298 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
3299 :
3300 0 : if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3301 : {
3302 0 : pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3303 : }
3304 : }
3305 : }
3306 0 : do
3307 : {
3308 : //Could take a while therefore check for Waitcrsr here.
3309 0 : if ( pImp )
3310 0 : pImp->CheckWaitCrsr();
3311 :
3312 0 : mbValidSize = sal_True;
3313 : //First format the column as this will relieve the stack a bit.
3314 : //Also set width and height of the column (if they are wrong)
3315 : //while we are at it.
3316 0 : SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
3317 :
3318 : // #i27399#
3319 : // Simply setting the column width based on the values returned by
3320 : // CalcColWidth does not work for automatic column width.
3321 0 : AdjustColumns( &rCol, sal_False );
3322 :
3323 0 : for ( sal_uInt16 i = 0; i < nNumCols; ++i )
3324 : {
3325 0 : pCol->Calc();
3326 : // ColumnFrms have a BodyFrm now, which needs to be calculated
3327 0 : pCol->Lower()->Calc();
3328 0 : if( pCol->Lower()->GetNext() )
3329 0 : pCol->Lower()->GetNext()->Calc(); // SwFtnCont
3330 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3331 : }
3332 :
3333 0 : ::CalcCntnt( this );
3334 :
3335 0 : pCol = (SwLayoutFrm*)Lower();
3336 : OSL_ENSURE( pCol && pCol->GetNext(), ":-( column making holidays?");
3337 : // set bMinDiff if no empty columns exist
3338 0 : bool bMinDiff = true;
3339 : // OD 28.03.2003 #108446# - check for all column content and all columns
3340 0 : while ( bMinDiff && pCol )
3341 : {
3342 0 : bMinDiff = 0 != pCol->ContainsCntnt();
3343 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3344 : }
3345 0 : pCol = (SwLayoutFrm*)Lower();
3346 : // OD 28.03.2003 #108446# - initialize local variable
3347 0 : SwFrm *pLow = NULL;
3348 0 : SwTwips nDiff = 0;
3349 0 : SwTwips nMaxFree = 0;
3350 0 : SwTwips nAllFree = LONG_MAX;
3351 : // set bFoundLower if there is at least one non-empty column
3352 0 : bool bFoundLower = false;
3353 0 : while( pCol )
3354 : {
3355 0 : SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
3356 0 : SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() -
3357 0 : (pLay->Prt().*fnRect->fnGetHeight)();
3358 0 : if( pLay->Lower() )
3359 : {
3360 0 : bFoundLower = true;
3361 0 : nInnerHeight += pLay->InnerHeight();
3362 : }
3363 0 : else if( nInnerHeight < 0 )
3364 0 : nInnerHeight = 0;
3365 :
3366 0 : if( pLay->GetNext() )
3367 : {
3368 0 : bFoundLower = true;
3369 0 : pLay = (SwLayoutFrm*)pLay->GetNext();
3370 : OSL_ENSURE( pLay->IsFtnContFrm(),"FtnContainer exspected" );
3371 0 : nInnerHeight += pLay->InnerHeight();
3372 0 : nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() -
3373 0 : (pLay->Prt().*fnRect->fnGetHeight)();
3374 : }
3375 0 : nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)();
3376 0 : if( nInnerHeight > nDiff )
3377 : {
3378 0 : nDiff = nInnerHeight;
3379 0 : nAllFree = 0;
3380 : }
3381 : else
3382 : {
3383 0 : if( nMaxFree < -nInnerHeight )
3384 0 : nMaxFree = -nInnerHeight;
3385 0 : if( nAllFree > -nInnerHeight )
3386 0 : nAllFree = -nInnerHeight;
3387 : }
3388 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3389 : }
3390 :
3391 0 : if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
3392 : {
3393 0 : SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
3394 : // Here we decide if growing is needed - this is the case, if
3395 : // column content (nDiff) or a Fly juts over.
3396 : // In sections with columns we take into account to set the size
3397 : // when having a non-empty Follow.
3398 0 : if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
3399 0 : ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
3400 : {
3401 0 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3402 : // The minimum must not be smaller than our PrtHeight as
3403 : // long as something juts over.
3404 0 : if( nMinimum < nPrtHeight )
3405 0 : nMinimum = nPrtHeight;
3406 : // The maximum must not be smaller than PrtHeight if
3407 : // something still juts over.
3408 0 : if( nMaximum < nPrtHeight )
3409 0 : nMaximum = nPrtHeight; // Robust, but will this ever happen?
3410 0 : if( !nDiff ) // If only Flys jut over, we grow by nMinDiff
3411 0 : nDiff = nMinDiff;
3412 : // If we should grow more than by nMinDiff we split it over
3413 : // the columns
3414 0 : if ( std::abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
3415 0 : nDiff /= nNumCols;
3416 :
3417 0 : if ( bMinDiff )
3418 : { // If no empty column exists, we want to grow at least
3419 : // by nMinDiff. Special case: If we are smaller than the
3420 : // minimal FrmHeight and PrtHeight is smaller than
3421 : // nMindiff we grow in a way that PrtHeight is exactly
3422 : // nMinDiff afterwards.
3423 0 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
3424 0 : if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff )
3425 0 : nDiff = std::max( nDiff, nMinDiff );
3426 0 : else if( nDiff < nMinDiff )
3427 0 : nDiff = nMinDiff - nPrtHeight + 1;
3428 : }
3429 : // nMaximum has a size which fits the content or the
3430 : // requested value from the surrounding therefore we don't
3431 : // need to exceed this value.
3432 0 : if( nDiff + nPrtHeight > nMaximum )
3433 0 : nDiff = nMaximum - nPrtHeight;
3434 : }
3435 0 : else if( nMaximum > nMinimum ) // We fit, do we still have some margin?
3436 : {
3437 0 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3438 0 : if ( nMaximum < nPrtHeight )
3439 0 : nDiff = nMaximum - nPrtHeight; // We grew over a working
3440 : // height and shrink back to it, but will this ever
3441 : // happen?
3442 : else
3443 : { // We have a new maximum, a size which fits for the content.
3444 0 : nMaximum = nPrtHeight;
3445 : // If the margin in the column is bigger than nMinDiff
3446 : // and we therefore drop under the minimum, we deflate
3447 : // a bit.
3448 0 : if ( !bNoBalance &&
3449 : // #i23129# - <nMinDiff> can be
3450 : // big, because of an object at the beginning of
3451 : // a column. Thus, decrease optimization here.
3452 : //nMaxFree >= nMinDiff &&
3453 0 : nMaxFree > 0 &&
3454 0 : ( !nAllFree ||
3455 0 : nMinimum < nPrtHeight - nMinDiff ) )
3456 : {
3457 0 : nMaxFree /= nNumCols; // disperse over the columns
3458 0 : nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // min nMinDiff
3459 0 : if( nPrtHeight + nDiff <= nMinimum ) // below the minimum?
3460 0 : nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3461 : }
3462 0 : else if( nAllFree )
3463 : {
3464 0 : nDiff = -nAllFree;
3465 0 : if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
3466 0 : nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3467 : }
3468 : }
3469 : }
3470 0 : if( nDiff ) // now we shrink or grow...
3471 : {
3472 0 : Size aOldSz( Prt().SSize() );
3473 0 : long nTop = (this->*fnRect->fnGetTopMargin)();
3474 0 : nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder -
3475 0 : (Frm().*fnRect->fnGetHeight)();
3476 0 : (Frm().*fnRect->fnAddBottom)( nDiff );
3477 : // #i68520#
3478 0 : if ( dynamic_cast<SwFlyFrm*>(this) )
3479 : {
3480 0 : dynamic_cast<SwFlyFrm*>(this)->InvalidateObjRectWithSpaces();
3481 : }
3482 0 : (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop );
3483 0 : ChgLowersProp( aOldSz );
3484 0 : NotifyLowerObjs();
3485 :
3486 : // #i3317# - reset temporarly consideration
3487 : // of wrapping style influence
3488 0 : SwPageFrm* pTmpPageFrm = FindPageFrm();
3489 0 : SwSortedObjs* pTmpObjs = pTmpPageFrm ? pTmpPageFrm->GetSortedObjs() : 0L;
3490 0 : if ( pTmpObjs )
3491 : {
3492 0 : sal_uInt32 i = 0;
3493 0 : for ( i = 0; i < pTmpObjs->Count(); ++i )
3494 : {
3495 0 : SwAnchoredObject* pAnchoredObj = (*pTmpObjs)[i];
3496 :
3497 0 : if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3498 : {
3499 0 : pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3500 : }
3501 : }
3502 : }
3503 : //Invalidate suitable to nicely balance the Frms.
3504 : //- Every first one after the second column gets a
3505 : // InvalidatePos();
3506 0 : pCol = (SwLayoutFrm*)Lower()->GetNext();
3507 0 : while ( pCol )
3508 : {
3509 0 : pLow = pCol->Lower();
3510 0 : if ( pLow )
3511 0 : pLow->_InvalidatePos();
3512 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3513 : }
3514 0 : if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
3515 : {
3516 : // If we created a Follow, we need to give its content
3517 : // the opportunity to flow back inside the CalcCntnt
3518 : SwCntntFrm* pTmpCntnt =
3519 0 : ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
3520 0 : if( pTmpCntnt )
3521 0 : pTmpCntnt->_InvalidatePos();
3522 : }
3523 : }
3524 : else
3525 0 : bEnd = true;
3526 : }
3527 : else
3528 0 : bEnd = true;
3529 :
3530 0 : } while ( !bEnd || !mbValidSize );
3531 : }
3532 : // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
3533 : // 2nd parameter to <true>.
3534 0 : ::CalcCntnt( this, true );
3535 0 : if( IsSctFrm() )
3536 : {
3537 : // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
3538 0 : ::CalcCntnt( this, true );
3539 0 : if( bBackLock )
3540 0 : ((SwSectionFrm*)this)->SetFtnLock( false );
3541 : }
3542 0 : }
3543 :
3544 0 : static SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, sal_uInt8 nInv )
3545 : {
3546 0 : SwSectionFrm* pSect = pCnt->FindSctFrm();
3547 : // If our CntntFrm is placed inside a table or a footnote, only sections
3548 : // which are also placed inside are meant.
3549 : // Exception: If a table is directly passed.
3550 0 : if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
3551 0 : ( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
3552 0 : return NULL;
3553 0 : if( nInv & INV_SIZE )
3554 0 : pSect->_InvalidateSize();
3555 0 : if( nInv & INV_POS )
3556 0 : pSect->_InvalidatePos();
3557 0 : if( nInv & INV_PRTAREA )
3558 0 : pSect->_InvalidatePrt();
3559 0 : SwFlowFrm *pFoll = pSect->GetFollow();
3560 : // Temporary separation from follow
3561 0 : pSect->SetFollow( NULL );
3562 0 : SwCntntFrm* pRet = pSect->FindLastCntnt();
3563 0 : pSect->SetFollow( pFoll );
3564 0 : return pRet;
3565 : }
3566 :
3567 0 : static SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, sal_uInt8 nInv )
3568 : {
3569 0 : if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
3570 0 : lcl_InvalidateSection( pTable, nInv );
3571 0 : if( nInv & INV_SIZE )
3572 0 : pTable->_InvalidateSize();
3573 0 : if( nInv & INV_POS )
3574 0 : pTable->_InvalidatePos();
3575 0 : if( nInv & INV_PRTAREA )
3576 0 : pTable->_InvalidatePrt();
3577 0 : return pTable->FindLastCntnt();
3578 : }
3579 :
3580 : static void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv );
3581 :
3582 0 : static void lcl_InvalidateCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3583 : {
3584 0 : SwCntntFrm *pLastTabCnt = NULL;
3585 0 : SwCntntFrm *pLastSctCnt = NULL;
3586 0 : while ( pCnt )
3587 : {
3588 0 : if( nInv & INV_SECTION )
3589 : {
3590 0 : if( pCnt->IsInSct() )
3591 : {
3592 : // See above at tables
3593 0 : if( !pLastSctCnt )
3594 0 : pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
3595 0 : if( pLastSctCnt == pCnt )
3596 0 : pLastSctCnt = NULL;
3597 : }
3598 : #if OSL_DEBUG_LEVEL > 0
3599 : else
3600 : OSL_ENSURE( !pLastSctCnt, "Where's the last SctCntnt?" );
3601 : #endif
3602 : }
3603 0 : if( nInv & INV_TABLE )
3604 : {
3605 0 : if( pCnt->IsInTab() )
3606 : {
3607 : // To not call FindTabFrm() for each CntntFrm of a table and
3608 : // then invalidate the table, we remember the last CntntFrm of
3609 : // the table and ignore IsInTab() until we are past it.
3610 : // When entering the table, LastSctCnt is set to null, so
3611 : // sections inside the table are correctly invalidated.
3612 : // If the table itself is in a section the
3613 : // invalidation is done three times, which is acceptable.
3614 0 : if( !pLastTabCnt )
3615 : {
3616 0 : pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
3617 0 : pLastSctCnt = NULL;
3618 : }
3619 0 : if( pLastTabCnt == pCnt )
3620 : {
3621 0 : pLastTabCnt = NULL;
3622 0 : pLastSctCnt = NULL;
3623 : }
3624 : }
3625 : #if OSL_DEBUG_LEVEL > 0
3626 : else
3627 : OSL_ENSURE( !pLastTabCnt, "Where's the last TabCntnt?" );
3628 : #endif
3629 : }
3630 :
3631 0 : if( nInv & INV_SIZE )
3632 0 : pCnt->Prepare( PREP_CLEAR, 0, false );
3633 0 : if( nInv & INV_POS )
3634 0 : pCnt->_InvalidatePos();
3635 0 : if( nInv & INV_PRTAREA )
3636 0 : pCnt->_InvalidatePrt();
3637 0 : if ( nInv & INV_LINENUM )
3638 0 : pCnt->InvalidateLineNum();
3639 0 : if ( pCnt->GetDrawObjs() )
3640 0 : lcl_InvalidateAllCntnt( pCnt, nInv );
3641 0 : pCnt = pCnt->GetNextCntntFrm();
3642 : }
3643 0 : }
3644 :
3645 0 : static void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3646 : {
3647 0 : SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
3648 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3649 : {
3650 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3651 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3652 : {
3653 0 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3654 0 : if ( pFly->IsFlyInCntFrm() )
3655 : {
3656 0 : ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3657 0 : if( nInv & INV_DIRECTION )
3658 0 : pFly->CheckDirChange();
3659 : }
3660 : }
3661 : }
3662 0 : }
3663 :
3664 0 : void SwRootFrm::InvalidateAllCntnt( sal_uInt8 nInv )
3665 : {
3666 : // First process all page bound FlyFrms.
3667 0 : SwPageFrm *pPage = (SwPageFrm*)Lower();
3668 0 : while( pPage )
3669 : {
3670 0 : pPage->InvalidateFlyLayout();
3671 0 : pPage->InvalidateFlyCntnt();
3672 0 : pPage->InvalidateFlyInCnt();
3673 0 : pPage->InvalidateLayout();
3674 0 : pPage->InvalidateCntnt();
3675 0 : pPage->InvalidatePage( pPage ); // So even the Turbo disappears if applicable
3676 :
3677 0 : if ( pPage->GetSortedObjs() )
3678 : {
3679 0 : const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3680 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3681 : {
3682 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3683 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3684 : {
3685 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3686 0 : ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3687 0 : if ( nInv & INV_DIRECTION )
3688 0 : pFly->CheckDirChange();
3689 : }
3690 : }
3691 : }
3692 0 : if( nInv & INV_DIRECTION )
3693 0 : pPage->CheckDirChange();
3694 0 : pPage = (SwPageFrm*)(pPage->GetNext());
3695 : }
3696 :
3697 : //Invalidate the whole document content and the character bound Flys here.
3698 0 : ::lcl_InvalidateCntnt( ContainsCntnt(), nInv );
3699 :
3700 0 : if( nInv & INV_PRTAREA )
3701 : {
3702 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
3703 0 : if( pSh )
3704 0 : pSh->InvalidateWindows( Frm() );
3705 : }
3706 0 : }
3707 :
3708 : /**
3709 : * Invalidate/re-calculate the position of all floating screen objects (Writer fly frames and
3710 : * drawing objects), that are anchored to paragraph or to character. (2004-03-16 #i11860#)
3711 : */
3712 0 : void SwRootFrm::InvalidateAllObjPos()
3713 : {
3714 0 : const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>(Lower());
3715 0 : while( pPageFrm )
3716 : {
3717 0 : pPageFrm->InvalidateFlyLayout();
3718 :
3719 0 : if ( pPageFrm->GetSortedObjs() )
3720 : {
3721 0 : const SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
3722 0 : for ( sal_uInt8 i = 0; i < rObjs.Count(); ++i )
3723 : {
3724 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3725 0 : const SwFmtAnchor& rAnch = pAnchoredObj->GetFrmFmt().GetAnchor();
3726 0 : if ((rAnch.GetAnchorId() != FLY_AT_PARA) &&
3727 0 : (rAnch.GetAnchorId() != FLY_AT_CHAR))
3728 : {
3729 : // only to paragraph and to character anchored objects are considered.
3730 0 : continue;
3731 : }
3732 : // #i28701# - special invalidation for anchored
3733 : // objects, whose wrapping style influence has to be considered.
3734 0 : if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
3735 0 : pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
3736 : else
3737 0 : pAnchoredObj->InvalidateObjPos();
3738 : }
3739 : }
3740 :
3741 0 : pPageFrm = static_cast<const SwPageFrm*>(pPageFrm->GetNext());
3742 : }
3743 0 : }
3744 :
3745 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|