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