xref: /aoo41x/main/sw/source/core/layout/wsfrm.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <hintids.hxx>
33 #include <hints.hxx>
34 #include <tools/pstm.hxx>
35 #include <vcl/outdev.hxx>
36 #include <svl/itemiter.hxx>
37 #include <editeng/brshitem.hxx>
38 #include <editeng/keepitem.hxx>
39 #include <editeng/brkitem.hxx>
40 #include <fmtornt.hxx>
41 #include <pagefrm.hxx>
42 #include <section.hxx>
43 #include <rootfrm.hxx>
44 #include <cntfrm.hxx>
45 #include <dcontact.hxx>
46 #include <anchoreddrawobject.hxx>
47 #include <fmtanchr.hxx>
48 #include <viewsh.hxx>
49 #include <viewimp.hxx>
50 #include "viewopt.hxx"
51 #include <doc.hxx>
52 #include <fesh.hxx>
53 #include <docsh.hxx>
54 #include <flyfrm.hxx>
55 #include <frmtool.hxx>
56 #include <ftninfo.hxx>
57 #include <dflyobj.hxx>
58 #include <fmtclbl.hxx>
59 #include <fmtfordr.hxx>
60 #include <fmtfsize.hxx>
61 #include <fmtpdsc.hxx>
62 #include <txtftn.hxx>
63 #include <fmtftn.hxx>
64 #include <fmtsrnd.hxx>
65 #include <ftnfrm.hxx>
66 #include <tabfrm.hxx>
67 #include <htmltbl.hxx>
68 #include <flyfrms.hxx>
69 #include <sectfrm.hxx>
70 #include <fmtclds.hxx>
71 #include <txtfrm.hxx>
72 #include <ndtxt.hxx>
73 #include <bodyfrm.hxx>
74 #include <cellfrm.hxx>
75 #include <dbg_lay.hxx>
76 #include <editeng/frmdiritem.hxx>
77 // OD 2004-05-24 #i28701#
78 #include <sortedobjs.hxx>
79 
80 
81 using namespace ::com::sun::star;
82 
83 
84 /*************************************************************************
85 |*
86 |*	SwFrm::SwFrm()
87 |*
88 |*	Ersterstellung		AK 12-Feb-1991
89 |*	Letzte Aenderung	MA 05. Apr. 94
90 |*
91 |*************************************************************************/
92 
93 SwFrm::SwFrm( SwModify *pMod, SwFrm* pSib ) :
94 	SwClient( pMod ),
95     // --> OD 2006-05-10 #i65250#
96     mnFrmId( SwFrm::mnLastFrmId++ ),
97     // <--
98     mpRoot( pSib ? pSib->getRootFrm() : 0 ),
99     pUpper( 0 ),
100     pNext( 0 ),
101     pPrev( 0 ),
102     pDrawObjs( 0 )
103     , bInfBody( sal_False )
104     , bInfTab ( sal_False )
105     , bInfFly ( sal_False )
106     , bInfFtn ( sal_False )
107     , bInfSct ( sal_False )
108 {
109 #ifdef DBG_UTIL
110     bFlag01 = bFlag02 = bFlag03 = bFlag04 = bFlag05 = 0;
111 #endif
112 
113 	ASSERT( pMod, "Kein Frameformat uebergeben." );
114     bInvalidR2L = bInvalidVert = 1;
115     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
116     bDerivedR2L = bDerivedVert = bRightToLeft = bVertical = bReverse = bVertLR = 0;
117 
118     bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche =
119     bFixSize = bColLocked = sal_False;
120     bCompletePaint = bInfInvalid = sal_True;
121 }
122 
123 bool SwFrm::KnowsFormat( const SwFmt& rFmt ) const
124 {
125     return GetRegisteredIn() == &rFmt;
126 }
127 
128 void SwFrm::RegisterToFormat( SwFmt& rFmt )
129 {
130     rFmt.Add( this );
131 }
132 
133 void SwFrm::CheckDir( sal_uInt16 nDir, sal_Bool bVert, sal_Bool bOnlyBiDi, sal_Bool bBrowse )
134 {
135     if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) )
136     {
137         bDerivedVert = 1;
138         if( FRMDIR_ENVIRONMENT == nDir )
139             bDerivedR2L = 1;
140         SetDirFlags( bVert );
141     }
142     else if( bVert )
143     {
144         bInvalidVert = 0;
145         if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
146             || bBrowse )
147         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
148         {
149             bVertical = 0;
150             bVertLR = 0;
151 		}
152         else
153        	{
154             bVertical = 1;
155             if(FRMDIR_VERT_TOP_RIGHT == nDir)
156 				bVertLR = 0;
157 	       	else if(FRMDIR_VERT_TOP_LEFT==nDir)
158 		       		bVertLR = 1;
159 		}
160     }
161     else
162     {
163         bInvalidR2L = 0;
164         if( FRMDIR_HORI_RIGHT_TOP == nDir )
165             bRightToLeft = 1;
166         else
167             bRightToLeft = 0;
168     }
169 }
170 
171 void SwFrm::CheckDirection( sal_Bool bVert )
172 {
173     if( bVert )
174     {
175         if( !IsHeaderFrm() && !IsFooterFrm() )
176         {
177             bDerivedVert = 1;
178             SetDirFlags( bVert );
179         }
180     }
181     else
182     {
183         bDerivedR2L = 1;
184         SetDirFlags( bVert );
185     }
186 }
187 
188 void SwSectionFrm::CheckDirection( sal_Bool bVert )
189 {
190     const SwFrmFmt* pFmt = GetFmt();
191     if( pFmt )
192     {
193         const ViewShell *pSh = getRootFrm()->GetCurrShell();
194         const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
195         CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
196                     bVert, sal_True, bBrowseMode );
197     }
198     else
199         SwFrm::CheckDirection( bVert );
200 }
201 
202 void SwFlyFrm::CheckDirection( sal_Bool bVert )
203 {
204     const SwFrmFmt* pFmt = GetFmt();
205     if( pFmt )
206     {
207         const ViewShell *pSh = getRootFrm()->GetCurrShell();
208         const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
209         CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
210                     bVert, sal_False, bBrowseMode );
211     }
212     else
213         SwFrm::CheckDirection( bVert );
214 }
215 
216 void SwTabFrm::CheckDirection( sal_Bool bVert )
217 {
218     const SwFrmFmt* pFmt = GetFmt();
219     if( pFmt )
220     {
221         const ViewShell *pSh = getRootFrm()->GetCurrShell();
222         const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
223         CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
224                     bVert, sal_True, bBrowseMode );
225     }
226     else
227         SwFrm::CheckDirection( bVert );
228 }
229 
230 void SwCellFrm::CheckDirection( sal_Bool bVert )
231 {
232     const SwFrmFmt* pFmt = GetFmt();
233     const SfxPoolItem* pItem;
234     // --> FME 2006-03-30 #b6402837# Check if the item is set, before actually
235     // using it. Otherwise the dynamic pool default is used, which may be set
236     // to LTR in case of OOo 1.0 documents.
237     // <--
238     if( pFmt && SFX_ITEM_SET == pFmt->GetItemState( RES_FRAMEDIR, sal_True, &pItem ) )
239     {
240         const SvxFrameDirectionItem* pFrmDirItem = static_cast<const SvxFrameDirectionItem*>(pItem);
241         const ViewShell *pSh = getRootFrm()->GetCurrShell();
242         const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
243         CheckDir( pFrmDirItem->GetValue(), bVert, sal_False, bBrowseMode );
244     }
245     else
246         SwFrm::CheckDirection( bVert );
247 }
248 
249 void SwTxtFrm::CheckDirection( sal_Bool bVert )
250 {
251     const ViewShell *pSh = getRootFrm()->GetCurrShell();
252     const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
253     CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert,
254               sal_True, bBrowseMode );
255 }
256 
257 /*************************************************************************/
258 void SwFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
259 {
260 	sal_uInt8 nInvFlags = 0;
261 
262 	if( pNew && RES_ATTRSET_CHG == pNew->Which() )
263 	{
264 		SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
265 		SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
266 		while( sal_True )
267 		{
268 			_UpdateAttrFrm( (SfxPoolItem*)aOIter.GetCurItem(),
269 						 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
270 			if( aNIter.IsAtEnd() )
271 				break;
272 			aNIter.NextItem();
273 			aOIter.NextItem();
274 		}
275 	}
276 	else
277 		_UpdateAttrFrm( pOld, pNew, nInvFlags );
278 
279 	if ( nInvFlags != 0 )
280 	{
281 		SwPageFrm *pPage = FindPageFrm();
282 		InvalidatePage( pPage );
283 		if ( nInvFlags & 0x01 )
284 		{
285 			_InvalidatePrt();
286 			if( !GetPrev() && IsTabFrm() && IsInSct() )
287 				FindSctFrm()->_InvalidatePrt();
288 		}
289 		if ( nInvFlags & 0x02 )
290 			_InvalidateSize();
291 		if ( nInvFlags & 0x04 )
292 			_InvalidatePos();
293 		if ( nInvFlags & 0x08 )
294 			SetCompletePaint();
295 		SwFrm *pNxt;
296 		if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
297 		{
298 			pNxt->InvalidatePage( pPage );
299 			if ( nInvFlags & 0x10 )
300 				pNxt->_InvalidatePos();
301 			if ( nInvFlags & 0x20 )
302 				pNxt->SetCompletePaint();
303 		}
304 	}
305 }
306 
307 void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
308 						 sal_uInt8 &rInvFlags )
309 {
310 	sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
311 	switch( nWhich )
312 	{
313 		case RES_BOX:
314 		case RES_SHADOW:
315 			Prepare( PREP_FIXSIZE_CHG );
316 			// hier kein break !
317 		case RES_LR_SPACE:
318 		case RES_UL_SPACE:
319 			rInvFlags |= 0x0B;
320 			break;
321 
322         case RES_HEADER_FOOTER_EAT_SPACING:
323             rInvFlags |= 0x03;
324             break;
325 
326 		case RES_BACKGROUND:
327 			rInvFlags |= 0x28;
328 			break;
329 
330 		case RES_KEEP:
331 			rInvFlags |= 0x04;
332 			break;
333 
334 		case RES_FRM_SIZE:
335 			ReinitializeFrmSizeAttrFlags();
336 			rInvFlags |= 0x13;
337 			break;
338 
339 		case RES_FMT_CHG:
340 			rInvFlags |= 0x0F;
341 			break;
342 
343         case RES_ROW_SPLIT:
344         {
345             if ( IsRowFrm() )
346             {
347                 sal_Bool bInFollowFlowRow = 0 != IsInFollowFlowRow();
348                 if ( bInFollowFlowRow || 0 != IsInSplitTableRow() )
349                 {
350                     SwTabFrm* pTab = FindTabFrm();
351                     if ( bInFollowFlowRow )
352                         pTab = pTab->FindMaster();
353                     pTab->SetRemoveFollowFlowLinePending( sal_True );
354                 }
355             }
356             break;
357         }
358         case RES_COL:
359 			ASSERT( sal_False, "Spalten fuer neuen FrmTyp?" );
360 			break;
361 
362 		default:
363 			/* do Nothing */;
364 	}
365 }
366 
367 /*************************************************************************
368 |*
369 |*	  SwFrm::Prepare()
370 |*	  Ersterstellung	MA 13. Apr. 93
371 |*	  Letzte Aenderung	MA 26. Jun. 96
372 |*
373 |*************************************************************************/
374 void SwFrm::Prepare( const PrepareHint, const void *, sal_Bool )
375 {
376 	/* Do nothing */
377 }
378 
379 /*************************************************************************
380 |*
381 |*	  SwFrm::InvalidatePage()
382 |*	  Beschreibung:		Invalidiert die Seite, in der der Frm gerade steht.
383 |*		Je nachdem ob es ein Layout, Cntnt oder FlyFrm ist wird die Seite
384 |*		entsprechend Invalidiert.
385 |*	  Ersterstellung	MA 22. Jul. 92
386 |*	  Letzte Aenderung	MA 14. Oct. 94
387 |*
388 |*************************************************************************/
389 void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
390 {
391     if ( !pPage )
392     {
393 		pPage = FindPageFrm();
394         // --> OD 2004-07-02 #i28701# - for at-character and as-character
395         // anchored Writer fly frames additionally invalidate also page frame
396         // its 'anchor character' is on.
397         if ( pPage && pPage->GetUpper() && IsFlyFrm() )
398         {
399             const SwFlyFrm* pFlyFrm = static_cast<const SwFlyFrm*>(this);
400             if ( pFlyFrm->IsAutoPos() || pFlyFrm->IsFlyInCntFrm() )
401             {
402                 // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
403                 // is replaced by method <FindPageFrmOfAnchor()>. It's return value
404                 // have to be checked.
405                 SwPageFrm* pPageFrmOfAnchor =
406                         const_cast<SwFlyFrm*>(pFlyFrm)->FindPageFrmOfAnchor();
407                 if ( pPageFrmOfAnchor && pPageFrmOfAnchor != pPage )
408                 // <--
409                 {
410                     InvalidatePage( pPageFrmOfAnchor );
411                 }
412             }
413         }
414         // <--
415     }
416 
417 	if ( pPage && pPage->GetUpper() )
418 	{
419 		if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
420 			return;
421 
422 		SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
423 		const SwFlyFrm *pFly = FindFlyFrm();
424 		if ( IsCntntFrm() )
425 		{
426 			if ( pRoot->IsTurboAllowed() )
427 			{
428 				// JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen
429 				//				will, kann es doch eine TurboAction bleiben.
430 				//	ODER????
431 				if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
432 					pRoot->SetTurbo( (const SwCntntFrm*)this );
433 				else
434 				{
435 					pRoot->DisallowTurbo();
436 					//Die Seite des Turbo koennte eine andere als die meinige
437 					//sein, deshalb muss sie invalidiert werden.
438 					const SwFrm *pTmp = pRoot->GetTurbo();
439 					pRoot->ResetTurbo();
440 					pTmp->InvalidatePage();
441 				}
442 			}
443 			if ( !pRoot->GetTurbo() )
444 			{
445 				if ( pFly )
446 				{	if( !pFly->IsLocked() )
447 					{
448 						if ( pFly->IsFlyInCntFrm() )
449 						{	pPage->InvalidateFlyInCnt();
450 							((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
451                             pFly->GetAnchorFrm()->InvalidatePage();
452 						}
453 						else
454 							pPage->InvalidateFlyCntnt();
455 					}
456 				}
457 				else
458 					pPage->InvalidateCntnt();
459 			}
460 		}
461 		else
462 		{
463 			pRoot->DisallowTurbo();
464 			if ( pFly )
465             {
466                 if ( !pFly->IsLocked() )
467 				{
468 					if ( pFly->IsFlyInCntFrm() )
469                     {
470                         pPage->InvalidateFlyInCnt();
471 						((SwFlyInCntFrm*)pFly)->InvalidateLayout();
472                         pFly->GetAnchorFrm()->InvalidatePage();
473 					}
474 					else
475 						pPage->InvalidateFlyLayout();
476 				}
477 			}
478 			else
479 				pPage->InvalidateLayout();
480 
481 			if ( pRoot->GetTurbo() )
482 			{	const SwFrm *pTmp = pRoot->GetTurbo();
483 				pRoot->ResetTurbo();
484 				pTmp->InvalidatePage();
485 			}
486 		}
487 		pRoot->SetIdleFlags();
488 
489 		const SwTxtFrm *pTxtFrm = dynamic_cast< const SwTxtFrm * >(this);
490 		if (pTxtFrm)
491 		{
492 			const SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
493 			if (pTxtNode && pTxtNode->IsGrammarCheckDirty())
494 				pRoot->SetNeedGrammarCheck( sal_True );
495 		}
496 	}
497 }
498 
499 /*************************************************************************
500 |*
501 |*	SwFrm::ChgSize()
502 |*
503 |*	Ersterstellung		AK 15-Feb-1991
504 |*	Letzte Aenderung	MA 18. Nov. 98
505 |*
506 |*************************************************************************/
507 Size SwFrm::ChgSize( const Size& aNewSize )
508 {
509     bFixSize = sal_True;
510 	const Size aOldSize( Frm().SSize() );
511 	if ( aNewSize == aOldSize )
512 		return aOldSize;
513 
514 	if ( GetUpper() )
515 	{
516         SWRECTFN2( this )
517         SwRect aNew( Point(0,0), aNewSize );
518         (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() );
519         long nNew = (aNew.*fnRect->fnGetHeight)();
520         long nDiff = nNew - (aFrm.*fnRect->fnGetHeight)();
521 		if( nDiff )
522 		{
523             if ( GetUpper()->IsFtnBossFrm() && HasFixSize() &&
524 				 NA_GROW_SHRINK !=
525 				 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
526 			{
527                 (aFrm.*fnRect->fnSetHeight)( nNew );
528                 SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff);
529 				if ( nReal != nDiff )
530                     (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal );
531 			}
532 			else
533 			{
534                 // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames
535                 // NOTE: neighbour frames are cell and column frames.
536                 if ( !bNeighb )
537                 {
538                     if ( nDiff > 0 )
539                         Grow( nDiff );
540                     else
541                         Shrink( -nDiff );
542 
543                     if ( GetUpper() && (aFrm.*fnRect->fnGetHeight)() != nNew )
544                         GetUpper()->_InvalidateSize();
545                 }
546 
547                 // Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat,
548                 // wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen,
549                 // wird die Breite jetzt gesetzt.
550                 (aFrm.*fnRect->fnSetHeight)( nNew );
551 			}
552 		}
553 	}
554 	else
555         aFrm.SSize( aNewSize );
556 
557 	if ( Frm().SSize() != aOldSize )
558 	{
559 		SwPageFrm *pPage = FindPageFrm();
560 		if ( GetNext() )
561 		{
562 			GetNext()->_InvalidatePos();
563 			GetNext()->InvalidatePage( pPage );
564 		}
565         if( IsLayoutFrm() )
566         {
567             if( IsRightToLeft() )
568                 _InvalidatePos();
569             if( ((SwLayoutFrm*)this)->Lower() )
570                 ((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
571         }
572 		_InvalidatePrt();
573 		_InvalidateSize();
574 		InvalidatePage( pPage );
575 	}
576 
577     return aFrm.SSize();
578 }
579 
580 /*************************************************************************
581 |*
582 |*	SwFrm::InsertBefore()
583 |*
584 |*	Beschreibung		SwFrm wird in eine bestehende Struktur eingefuegt
585 |* 						Eingefuegt wird unterhalb des Parent und entweder
586 |* 						vor pBehind oder am Ende der Kette wenn pBehind
587 |* 						leer ist.
588 |*	Letzte Aenderung	MA 06. Aug. 99
589 |*
590 |*************************************************************************/
591 void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
592 {
593 	ASSERT( pParent, "Kein Parent fuer Insert." );
594 	ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
595 			"Framebaum inkonsistent." );
596 
597 	pUpper = pParent;
598 	pNext = pBehind;
599 	if( pBehind )
600 	{	//Einfuegen vor pBehind.
601 		if( 0 != (pPrev = pBehind->pPrev) )
602 			pPrev->pNext = this;
603 		else
604 			pUpper->pLower = this;
605 		pBehind->pPrev = this;
606 	}
607 	else
608 	{	//Einfuegen am Ende, oder als ersten Node im Unterbaum
609 		pPrev = pUpper->Lower();
610 		if ( pPrev )
611 		{
612 			while( pPrev->pNext )
613 				pPrev = pPrev->pNext;
614 			pPrev->pNext = this;
615 		}
616 		else
617 			pUpper->pLower = this;
618 	}
619 }
620 
621 /*************************************************************************
622 |*
623 |*	SwFrm::InsertBehind()
624 |*
625 |*	Beschreibung		SwFrm wird in eine bestehende Struktur eingefuegt
626 |* 						Eingefuegt wird unterhalb des Parent und entweder
627 |* 						hinter pBefore oder am Anfang der Kette wenn pBefore
628 |* 						leer ist.
629 |*	Letzte Aenderung	MA 06. Aug. 99
630 |*
631 |*************************************************************************/
632 void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
633 {
634 	ASSERT( pParent, "Kein Parent fuer Insert." );
635 	ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
636 			"Framebaum inkonsistent." );
637 
638 	pUpper = pParent;
639 	pPrev = pBefore;
640 	if ( pBefore )
641 	{
642 		//Einfuegen hinter pBefore
643 		if ( 0 != (pNext = pBefore->pNext) )
644 			pNext->pPrev = this;
645 		pBefore->pNext = this;
646 	}
647 	else
648 	{
649 		//Einfuegen am Anfang der Kette
650 		pNext = pParent->Lower();
651 		if ( pParent->Lower() )
652 			pParent->Lower()->pPrev = this;
653 		pParent->pLower = this;
654 	}
655 }
656 
657 /*************************************************************************
658 |*
659 |*	SwFrm::InsertGroup()
660 |*
661 |*	Beschreibung		Eine Kette von SwFrms wird in eine bestehende Struktur
662 |* 						eingefuegt
663 |*	Letzte Aenderung	AMA 9. Dec. 97
664 |*
665 |*  Bisher wird dies genutzt, um einen SectionFrame, der ggf. schon Geschwister
666 |*	mit sich bringt, in eine bestehende Struktur einzufuegen.
667 |*
668 |*  Wenn man den dritten Parameter als NULL uebergibt, entspricht
669 |*  diese Methode dem SwFrm::InsertBefore(..), nur eben mit Geschwistern.
670 |*
671 |*  Wenn man einen dritten Parameter uebergibt, passiert folgendes:
672 |*  this wird pNext von pParent,
673 |*  pSct wird pNext vom Letzten der this-Kette,
674 |*  pBehind wird vom pParent an den pSct umgehaengt.
675 |*	Dies dient dazu: ein SectionFrm (this) wird nicht als
676 |*	Kind an einen anderen SectionFrm (pParent) gehaengt, sondern pParent
677 |*	wird in zwei Geschwister aufgespalten (pParent+pSct) und this dazwischen
678 |*  eingebaut.
679 |*
680 |*************************************************************************/
681 void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
682 {
683 	ASSERT( pParent, "Kein Parent fuer Insert." );
684 	ASSERT( (!pBehind || (pBehind && ( pParent == pBehind->GetUpper())
685 			|| ( pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm() ) ) ),
686 			"Framebaum inkonsistent." );
687 	if( pSct )
688 	{
689 		pUpper = pParent->GetUpper();
690 		SwFrm *pLast = this;
691 		while( pLast->GetNext() )
692 		{
693 			pLast = pLast->GetNext();
694 			pLast->pUpper = GetUpper();
695 		}
696 		if( pBehind )
697 		{
698 			pLast->pNext = pSct;
699 			pSct->pPrev = pLast;
700 			pSct->pNext = pParent->GetNext();
701 		}
702 		else
703 		{
704 			pLast->pNext = pParent->GetNext();
705 			if( pLast->GetNext() )
706 				pLast->GetNext()->pPrev = pLast;
707 		}
708 		pParent->pNext = this;
709 		pPrev = pParent;
710 		if( pSct->GetNext() )
711 			pSct->GetNext()->pPrev = pSct;
712 		while( pLast->GetNext() )
713 		{
714 			pLast = pLast->GetNext();
715 			pLast->pUpper = GetUpper();
716 		}
717 		if( pBehind )
718 		{	//Einfuegen vor pBehind.
719 			if( pBehind->GetPrev() )
720 				pBehind->GetPrev()->pNext = NULL;
721 			else
722 				pBehind->GetUpper()->pLower = NULL;
723 			pBehind->pPrev = NULL;
724 			SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
725 			if( pTmp->Lower() )
726 			{
727 				ASSERT( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
728 				pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
729 				ASSERT( pTmp, "InsertGrp: Missing ColBody" );
730 			}
731 			pBehind->pUpper = pTmp;
732 			pBehind->GetUpper()->pLower = pBehind;
733 			pLast = pBehind->GetNext();
734 			while ( pLast )
735 			{
736 				pLast->pUpper = pBehind->GetUpper();
737 				pLast = pLast->GetNext();
738 			};
739 		}
740 		else
741 		{
742 			ASSERT( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
743 			delete ((SwSectionFrm*)pSct);
744 		}
745 	}
746 	else
747 	{
748 		pUpper = (SwLayoutFrm*)pParent;
749 		SwFrm *pLast = this;
750 		while( pLast->GetNext() )
751 		{
752 			pLast = pLast->GetNext();
753 			pLast->pUpper = GetUpper();
754 		}
755 		pLast->pNext = pBehind;
756 		if( pBehind )
757 		{	//Einfuegen vor pBehind.
758 			if( 0 != (pPrev = pBehind->pPrev) )
759 				pPrev->pNext = this;
760 			else
761 				pUpper->pLower = this;
762 			pBehind->pPrev = pLast;
763 		}
764 		else
765 		{	//Einfuegen am Ende, oder des ersten Nodes im Unterbaum
766 			pPrev = pUpper->Lower();
767 			if ( pPrev )
768 			{
769 				while( pPrev->pNext )
770 					pPrev = pPrev->pNext;
771 				pPrev->pNext = this;
772 			}
773 			else
774 				pUpper->pLower = this;
775 		}
776 	}
777 }
778 
779 /*************************************************************************
780 |*
781 |*	SwFrm::Remove()
782 |*
783 |*	Ersterstellung		AK 01-Mar-1991
784 |*	Letzte Aenderung	MA 07. Dec. 95
785 |*
786 |*************************************************************************/
787 void SwFrm::Remove()
788 {
789 	ASSERT( pUpper, "Removen ohne Upper?" );
790 
791 	if( pPrev )
792 		// einer aus der Mitte wird removed
793 		pPrev->pNext = pNext;
794 	else
795 	{	// der erste in einer Folge wird removed
796 		ASSERT( pUpper->pLower == this, "Layout inkonsistent." );
797 		pUpper->pLower = pNext;
798 	}
799 	if( pNext )
800 		pNext->pPrev = pPrev;
801 
802 	// Verbindung kappen.
803 	pNext  = pPrev  = 0;
804 	pUpper = 0;
805 }
806 /*************************************************************************
807 |*
808 |*	SwCntntFrm::Paste()
809 |*
810 |*	Ersterstellung		MA 23. Feb. 94
811 |*	Letzte Aenderung	MA 09. Sep. 98
812 |*
813 |*************************************************************************/
814 void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
815 {
816 	ASSERT( pParent, "Kein Parent fuer Paste." );
817 	ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
818 	ASSERT( pParent != this, "Bin selbst der Parent." );
819 	ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
820 	ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
821 			"Bin noch irgendwo angemeldet." );
822     ASSERT( !pSibling || pSibling->IsFlowFrm(),
823             "<SwCntntFrm::Paste(..)> - sibling not of expected type." )
824 
825 	//In den Baum einhaengen.
826 	InsertBefore( (SwLayoutFrm*)pParent, pSibling );
827 
828 	SwPageFrm *pPage = FindPageFrm();
829 	_InvalidateAll();
830 	InvalidatePage( pPage );
831 
832 	if( pPage )
833 	{
834 		pPage->InvalidateSpelling();
835         pPage->InvalidateSmartTags();   // SMARTTAGS
836         pPage->InvalidateAutoCompleteWords();
837         pPage->InvalidateWordCount();
838 	}
839 
840 	if ( GetNext() )
841 	{
842 		SwFrm* pNxt = GetNext();
843 		pNxt->_InvalidatePrt();
844 		pNxt->_InvalidatePos();
845 		pNxt->InvalidatePage( pPage );
846 		if( pNxt->IsSctFrm() )
847 			pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
848 		if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
849 			pNxt->Prepare( PREP_FTN, 0, sal_False );
850 	}
851 
852 	if ( Frm().Height() )
853         pParent->Grow( Frm().Height() );
854 
855 	if ( Frm().Width() != pParent->Prt().Width() )
856 		Prepare( PREP_FIXSIZE_CHG );
857 
858 	if ( GetPrev() )
859 	{
860 		if ( IsFollow() )
861 			//Ich bin jetzt direkter Nachfolger meines Masters geworden
862 			((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
863 		else
864 		{
865 			if ( GetPrev()->Frm().Height() !=
866 				 GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
867 				//Umrandung zu beruecksichtigen?
868 				GetPrev()->_InvalidatePrt();
869             // OD 18.02.2003 #104989# - force complete paint of previous frame,
870             // if frame is inserted at the end of a section frame, in order to
871             // get subsidiary lines repainted for the section.
872             if ( pParent->IsSctFrm() && !GetNext() )
873             {
874                 // force complete paint of previous frame, if new inserted frame
875                 // in the section is the last one.
876                 GetPrev()->SetCompletePaint();
877             }
878 			GetPrev()->InvalidatePage( pPage );
879 		}
880 	}
881 	if ( IsInFtn() )
882 	{
883 		SwFrm* pFrm = GetIndPrev();
884 		if( pFrm && pFrm->IsSctFrm() )
885 			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
886 		if( pFrm )
887 			pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
888 		if( !GetNext() )
889 		{
890 			pFrm = FindFtnFrm()->GetNext();
891 			if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
892 				pFrm->_InvalidatePrt();
893 		}
894 	}
895 
896 	_InvalidateLineNum();
897 	SwFrm *pNxt = FindNextCnt();
898 	if ( pNxt  )
899 	{
900 		while ( pNxt && pNxt->IsInTab() )
901 		{
902 			if( 0 != (pNxt = pNxt->FindTabFrm()) )
903 				pNxt = pNxt->FindNextCnt();
904 		}
905 		if ( pNxt )
906 		{
907 			pNxt->_InvalidateLineNum();
908 			if ( pNxt != GetNext() )
909 				pNxt->InvalidatePage();
910 		}
911 	}
912 }
913 
914 /*************************************************************************
915 |*
916 |*	SwCntntFrm::Cut()
917 |*
918 |*	Ersterstellung		AK 14-Feb-1991
919 |*	Letzte Aenderung	MA 09. Sep. 98
920 |*
921 |*************************************************************************/
922 void SwCntntFrm::Cut()
923 {
924 	ASSERT( GetUpper(), "Cut ohne Upper()." );
925 
926 	SwPageFrm *pPage = FindPageFrm();
927 	InvalidatePage( pPage );
928 	SwFrm *pFrm = GetIndPrev();
929 	if( pFrm )
930 	{
931 		if( pFrm->IsSctFrm() )
932 			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
933 		if ( pFrm && pFrm->IsCntntFrm() )
934 		{
935 			pFrm->_InvalidatePrt();
936 			if( IsInFtn() )
937 				pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
938 		}
939         // --> OD 2004-07-15 #i26250# - invalidate printing area of previous
940         // table frame.
941         else if ( pFrm && pFrm->IsTabFrm() )
942         {
943             pFrm->InvalidatePrt();
944         }
945         // <--
946 	}
947 
948 	SwFrm *pNxt = FindNextCnt();
949 	if ( pNxt )
950 	{
951 		while ( pNxt && pNxt->IsInTab() )
952 		{
953 			if( 0 != (pNxt = pNxt->FindTabFrm()) )
954 				pNxt = pNxt->FindNextCnt();
955 		}
956 		if ( pNxt )
957 		{
958 			pNxt->_InvalidateLineNum();
959 			if ( pNxt != GetNext() )
960 				pNxt->InvalidatePage();
961 		}
962 	}
963 
964 	if( 0 != (pFrm = GetIndNext()) )
965 	{	//Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
966 		//berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders.
967 		pFrm->_InvalidatePrt();
968 		pFrm->_InvalidatePos();
969 		pFrm->InvalidatePage( pPage );
970 		if( pFrm->IsSctFrm() )
971 		{
972 			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
973 			if( pFrm )
974 			{
975 				pFrm->_InvalidatePrt();
976 				pFrm->_InvalidatePos();
977 				pFrm->InvalidatePage( pPage );
978 			}
979 		}
980 		if( pFrm && IsInFtn() )
981 			pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
982 		if( IsInSct() && !GetPrev() )
983 		{
984 			SwSectionFrm* pSct = FindSctFrm();
985 			if( !pSct->IsFollow() )
986 			{
987 				pSct->_InvalidatePrt();
988 				pSct->InvalidatePage( pPage );
989 			}
990 		}
991 	}
992 	else
993 	{
994 		InvalidateNextPos();
995 		//Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
996 		if ( 0 != (pFrm = GetPrev()) )
997 		{	pFrm->SetRetouche();
998 			pFrm->Prepare( PREP_WIDOWS_ORPHANS );
999 			pFrm->_InvalidatePos();
1000 			pFrm->InvalidatePage( pPage );
1001 		}
1002 		//Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss
1003 		//er die Retouche uebernehmen.
1004 		//Ausserdem kann eine Leerseite entstanden sein.
1005 		else
1006 		{	SwRootFrm *pRoot = getRootFrm();
1007 			if ( pRoot )
1008 			{
1009 				pRoot->SetSuperfluous();
1010 				GetUpper()->SetCompletePaint();
1011 				GetUpper()->InvalidatePage( pPage );
1012 			}
1013 			if( IsInSct() )
1014 			{
1015 				SwSectionFrm* pSct = FindSctFrm();
1016 				if( !pSct->IsFollow() )
1017 				{
1018 					pSct->_InvalidatePrt();
1019 					pSct->InvalidatePage( pPage );
1020 				}
1021 			}
1022             // --> FME 2005-08-03 #i52253# The master table should take care
1023             // of removing the follow flow line.
1024             if ( IsInTab() )
1025             {
1026                 SwTabFrm* pThisTab = FindTabFrm();
1027                 SwTabFrm* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : 0;
1028                 if ( pMasterTab )
1029                 {
1030                     pMasterTab->_InvalidatePos();
1031                     pMasterTab->SetRemoveFollowFlowLinePending( sal_True );
1032                 }
1033             }
1034             // <--
1035 		}
1036 	}
1037 	//Erst removen, dann Upper Shrinken.
1038 	SwLayoutFrm *pUp = GetUpper();
1039 	Remove();
1040 	if ( pUp )
1041 	{
1042         SwSectionFrm *pSct = 0;
1043         if ( !pUp->Lower() &&
1044              ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) ||
1045                ( pUp->IsInSct() &&
1046                  // -->  FME 2004-06-03 #i29438#
1047                  // We have to consider the case that the section may be "empty"
1048                  // except from a temporary empty table frame.
1049                  // This can happen due to the new cell split feature.
1050                  !pUp->IsCellFrm() &&
1051                  // <--
1052                  // --> OD 2006-01-04 #126020# - adjust check for empty section
1053                  // --> OD 2006-02-01 #130797# - correct fix #126020#
1054                  !(pSct = pUp->FindSctFrm())->ContainsCntnt() &&
1055                  !pSct->ContainsAny( true ) ) ) )
1056                  // <--
1057         {
1058 			if ( pUp->GetUpper() )
1059 			{
1060                 // --> OD 2006-09-25 #b6448963#
1061                 // prevent delete of <ColLocked> footnote frame
1062 //                if( pUp->IsFtnFrm() )
1063                 if ( pUp->IsFtnFrm() && !pUp->IsColLocked())
1064                 // <--
1065 				{
1066 					if( pUp->GetNext() && !pUp->GetPrev() )
1067 					{
1068 						SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
1069 						if( pTmp )
1070 							pTmp->_InvalidatePrt();
1071 					}
1072 					pUp->Cut();
1073 					delete pUp;
1074 				}
1075                 else
1076                 {
1077                     // --> OD 2006-09-25 #b6448963#
1078 //                    if ( pSct->IsColLocked() || !pSct->IsInFtn() )
1079                     if ( pSct->IsColLocked() || !pSct->IsInFtn() ||
1080                          ( pUp->IsFtnFrm() && pUp->IsColLocked() ) )
1081                     // <--
1082 					{
1083 						pSct->DelEmpty( sal_False );
1084                         // Wenn ein gelockter Bereich nicht geloescht werden darf,
1085                         // so ist zumindest seine Groesse durch das Entfernen seines
1086                         // letzten Contents ungueltig geworden.
1087 						pSct->_InvalidateSize();
1088 					}
1089 					else
1090 					{
1091 						pSct->DelEmpty( sal_True );
1092 						delete pSct;
1093 					}
1094 				}
1095 			}
1096 		}
1097         else
1098         {
1099             SWRECTFN( this )
1100             long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1101             if( nFrmHeight )
1102                 pUp->Shrink( nFrmHeight );
1103         }
1104 	}
1105 }
1106 
1107 /*************************************************************************
1108 |*
1109 |*	SwLayoutFrm::Paste()
1110 |*
1111 |*	Ersterstellung		MA 23. Feb. 94
1112 |*	Letzte Aenderung	MA 23. Feb. 94
1113 |*
1114 |*************************************************************************/
1115 void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
1116 {
1117 	ASSERT( pParent, "Kein Parent fuer Paste." );
1118 	ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
1119 	ASSERT( pParent != this, "Bin selbst der Parent." );
1120 	ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
1121 	ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
1122 			"Bin noch irgendwo angemeldet." );
1123 
1124 	//In den Baum einhaengen.
1125 	InsertBefore( (SwLayoutFrm*)pParent, pSibling );
1126 
1127     // OD 24.10.2002 #103517# - correct setting of variable <fnRect>
1128     // <fnRect> is used for the following:
1129     // (1) To invalidate the frame's size, if its size, which has to be the
1130     //      same as its upper/parent, differs from its upper's/parent's.
1131     // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its
1132     //      size, which is not determined by its upper/parent.
1133     // Which size is which depends on the frame type and the layout direction
1134     // (vertical or horizontal).
1135     // There are the following cases:
1136     // (A) Header and footer frames both in vertical and in horizontal layout
1137     //      have to size the width to the upper/parent. A dimension in the height
1138     //      has to cause a adjustment/grow of the upper/parent.
1139     //      --> <fnRect> = fnRectHori
1140     // (B) Cell and column frames in vertical layout, the width has to be the
1141     //          same as upper/parent and a dimension in height causes adjustment/grow
1142     //          of the upper/parent.
1143     //          --> <fnRect> = fnRectHori
1144     //      in horizontal layout the other way around
1145     //          --> <fnRect> = fnRectVert
1146     // (C) Other frames in vertical layout, the height has to be the
1147     //          same as upper/parent and a dimension in width causes adjustment/grow
1148     //          of the upper/parent.
1149     //          --> <fnRect> = fnRectVert
1150     //      in horizontal layout the other way around
1151     //          --> <fnRect> = fnRectHori
1152     //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert;
1153     SwRectFn fnRect;
1154     if ( IsHeaderFrm() || IsFooterFrm() )
1155         fnRect = fnRectHori;
1156     else if ( IsCellFrm() || IsColumnFrm() )
1157     	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1158         fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert );
1159     else
1160     	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1161         fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
1162 
1163 
1164     if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)())
1165 		_InvalidateSize();
1166 	_InvalidatePos();
1167 	const SwPageFrm *pPage = FindPageFrm();
1168 	InvalidatePage( pPage );
1169 	SwFrm *pFrm;
1170 	if( !IsColumnFrm() )
1171 	{
1172 		if( 0 != ( pFrm = GetIndNext() ) )
1173 		{
1174 			pFrm->_InvalidatePos();
1175 			if( IsInFtn() )
1176 			{
1177 				if( pFrm->IsSctFrm() )
1178 					pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1179 				if( pFrm )
1180 					pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
1181 			}
1182 		}
1183 		if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
1184 		{
1185 			if( pFrm->IsSctFrm() )
1186 				pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1187 			if( pFrm )
1188 				pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
1189 		}
1190 	}
1191 
1192     if( (Frm().*fnRect->fnGetHeight)() )
1193 	{
1194 		// AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
1195 		// die sich nicht in Rahmen befinden
1196 		sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
1197 				((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
1198 				: NA_GROW_SHRINK;
1199         SwTwips nGrow = (Frm().*fnRect->fnGetHeight)();
1200 		if( NA_ONLY_ADJUST == nAdjust )
1201 			AdjustNeighbourhood( nGrow );
1202 		else
1203 		{
1204 			SwTwips nReal = 0;
1205 			if( NA_ADJUST_GROW == nAdjust )
1206 				nReal = AdjustNeighbourhood( nGrow );
1207 			if( nReal < nGrow )
1208                 nReal += pParent->Grow( nGrow - nReal );
1209 			if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
1210 				AdjustNeighbourhood( nGrow - nReal );
1211 		}
1212 	}
1213 }
1214 
1215 /*************************************************************************
1216 |*
1217 |*	SwLayoutFrm::Cut()
1218 |*
1219 |*	Ersterstellung		MA 23. Feb. 94
1220 |*	Letzte Aenderung	MA 23. Feb. 94
1221 |*
1222 |*************************************************************************/
1223 void SwLayoutFrm::Cut()
1224 {
1225 	if ( GetNext() )
1226 		GetNext()->_InvalidatePos();
1227 
1228     SWRECTFN( this )
1229     SwTwips nShrink = (Frm().*fnRect->fnGetHeight)();
1230 
1231 	//Erst removen, dann Upper Shrinken.
1232 	SwLayoutFrm *pUp = GetUpper();
1233 
1234 	// AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
1235 	// die sich nicht in Rahmen befinden
1236 
1237 	// Remove must not be called before a AdjustNeighbourhood, but it has to
1238 	// be called before the upper-shrink-call, if the upper-shrink takes care
1239 	// of his content
1240 	if ( pUp && nShrink )
1241 	{
1242 		if( pUp->IsFtnBossFrm() )
1243 		{
1244 			sal_uInt8 nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
1245 			if( NA_ONLY_ADJUST == nAdjust )
1246 				AdjustNeighbourhood( -nShrink );
1247 			else
1248 			{
1249 				SwTwips nReal = 0;
1250 				if( NA_ADJUST_GROW == nAdjust )
1251 					nReal = -AdjustNeighbourhood( -nShrink );
1252 				if( nReal < nShrink )
1253 				{
1254                     SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)();
1255                     (Frm().*fnRect->fnSetHeight)( 0 );
1256                     nReal += pUp->Shrink( nShrink - nReal );
1257                     (Frm().*fnRect->fnSetHeight)( nOldHeight );
1258 				}
1259 				if( NA_GROW_ADJUST == nAdjust && nReal < nShrink )
1260 					AdjustNeighbourhood( nReal - nShrink );
1261 			}
1262 			Remove();
1263 		}
1264 		else
1265 		{
1266 			Remove();
1267             pUp->Shrink( nShrink );
1268 		}
1269 	}
1270 	else
1271 		Remove();
1272 
1273 	if( pUp && !pUp->Lower() )
1274 	{
1275 		pUp->SetCompletePaint();
1276 		pUp->InvalidatePage();
1277 	}
1278 }
1279 
1280 /*************************************************************************
1281 |*
1282 |*	SwFrm::Grow()
1283 |*
1284 |*	Ersterstellung		AK 19-Feb-1991
1285 |*	Letzte Aenderung	MA 05. May. 94
1286 |*
1287 |*************************************************************************/
1288 SwTwips SwFrm::Grow( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1289 {
1290 	ASSERT( nDist >= 0, "Negatives Wachstum?" );
1291 
1292 	PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )
1293 
1294 	if ( nDist )
1295 	{
1296         SWRECTFN( this )
1297 
1298         SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1299         if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) )
1300             nDist = LONG_MAX - nPrtHeight;
1301 
1302 		if ( IsFlyFrm() )
1303             return ((SwFlyFrm*)this)->_Grow( nDist, bTst );
1304 		else if( IsSctFrm() )
1305             return ((SwSectionFrm*)this)->_Grow( nDist, bTst );
1306 		else
1307 		{
1308             const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1309             if ( pThisCell )
1310             {
1311                 const SwTabFrm* pTab = FindTabFrm();
1312 
1313                 // NEW TABLES
1314                 if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
1315                      pThisCell->GetLayoutRowSpan() < 1 )
1316                     return 0;
1317             }
1318 
1319             const SwTwips nReal = GrowFrm( nDist, bTst, bInfo );
1320 			if( !bTst )
1321             {
1322                 nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1323                 (Prt().*fnRect->fnSetHeight)( nPrtHeight +
1324                         ( IsCntntFrm() ? nDist : nReal ) );
1325             }
1326 			return nReal;
1327 		}
1328 	}
1329 	return 0L;
1330 }
1331 
1332 /*************************************************************************
1333 |*
1334 |*	SwFrm::Shrink()
1335 |*
1336 |*	Ersterstellung		AK 14-Feb-1991
1337 |*	Letzte Aenderung	MA 05. May. 94
1338 |*
1339 |*************************************************************************/
1340 SwTwips SwFrm::Shrink( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1341 {
1342 	ASSERT( nDist >= 0, "Negative Verkleinerung?" );
1343 
1344 	PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )
1345 
1346 	if ( nDist )
1347 	{
1348 		if ( IsFlyFrm() )
1349             return ((SwFlyFrm*)this)->_Shrink( nDist, bTst );
1350 		else if( IsSctFrm() )
1351             return ((SwSectionFrm*)this)->_Shrink( nDist, bTst );
1352 		else
1353 		{
1354             const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1355             if ( pThisCell )
1356             {
1357                 const SwTabFrm* pTab = FindTabFrm();
1358 
1359                 // NEW TABLES
1360                 if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
1361                      pThisCell->GetLayoutRowSpan() < 1 )
1362                     return 0;
1363             }
1364 
1365             SWRECTFN( this )
1366             SwTwips nReal = (Frm().*fnRect->fnGetHeight)();
1367             ShrinkFrm( nDist, bTst, bInfo );
1368             nReal -= (Frm().*fnRect->fnGetHeight)();
1369 			if( !bTst )
1370             {
1371                 const SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1372                 (Prt().*fnRect->fnSetHeight)( nPrtHeight -
1373                         ( IsCntntFrm() ? nDist : nReal ) );
1374             }
1375 			return nReal;
1376 		}
1377 	}
1378 	return 0L;
1379 }
1380 
1381 /*************************************************************************
1382 |*
1383 |*	SwFrm::AdjustNeighbourhood()
1384 |*
1385 |*	Beschreibung		Wenn sich die Groesse eines Frm's direkt unterhalb
1386 |* 		eines Fussnotenbosses (Seite/Spalte) veraendert hat, so muss dieser
1387 |*  	"Normalisiert" werden.
1388 |* 		Es gibt dort immer einen Frame, der den "maximal moeglichen" Raum
1389 |*		einnimmt (der Frame, der den Body.Text enhaelt) und keinen oder
1390 |* 		mehrere Frames die den Platz einnehmen den sie halt brauchen
1391 |* 		(Kopf-/Fussbereich, Fussnoten).
1392 |*		Hat sich einer der Frames veraendert, so muss der Body-Text-Frame
1393 |*		entsprechen wachsen oder schrumpfen; unabhaegig davon, dass er fix ist.
1394 |* 		!! Ist es moeglich dies allgemeiner zu loesen, also nicht auf die
1395 |* 		Seite beschraenkt und nicht auf einen Speziellen Frame, der den
1396 |* 		maximalen Platz einnimmt (gesteuert ueber Attribut FrmSize)? Probleme:
1397 |* 		Was ist wenn mehrere Frames nebeneinander stehen, die den maximalen
1398 |* 		Platz einnehmen?
1399 |*		Wie wird der Maximale Platz berechnet?
1400 |* 		Wie klein duerfen diese Frames werden?
1401 |*
1402 |* 		Es wird auf jeden Fall nur so viel Platz genehmigt, dass ein
1403 |* 		Minimalwert fuer die Hoehe des Bodys nicht unterschritten wird.
1404 |*
1405 |*	Parameter: nDiff ist der Betrag, um den Platz geschaffen werden muss
1406 |*
1407 |*	Ersterstellung		MA 07. May. 92
1408 |*	Letzte Aenderung	AMA 02. Nov. 98
1409 |*
1410 |*************************************************************************/
1411 SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, sal_Bool bTst )
1412 {
1413 	PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );
1414 
1415 	if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten
1416 		return 0L;
1417 
1418     const ViewShell *pSh = getRootFrm()->GetCurrShell();
1419     const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1420 
1421 	//Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er
1422 	//Spalten enthaelt.
1423 	if ( IsPageBodyFrm() && (!bBrowse ||
1424 		  (((SwLayoutFrm*)this)->Lower() &&
1425 		   ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
1426 		return 0L;
1427 
1428 	//In der BrowseView kann der PageFrm selbst ersteinmal einiges von den
1429 	//Wuenschen abfangen.
1430 	long nBrowseAdd = 0;
1431 	if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms
1432 	{
1433 		ViewShell *pViewShell = getRootFrm()->GetCurrShell();
1434 		SwLayoutFrm *pUp = GetUpper();
1435 		long nChg;
1436 		const long nUpPrtBottom = pUp->Frm().Height() -
1437 								  pUp->Prt().Height() - pUp->Prt().Top();
1438 		SwRect aInva( pUp->Frm() );
1439 		if ( pViewShell )
1440 		{
1441 			aInva.Pos().X() = pViewShell->VisArea().Left();
1442 			aInva.Width( pViewShell->VisArea().Width() );
1443 		}
1444 		if ( nDiff > 0 )
1445 		{
1446 			nChg = BROWSE_HEIGHT - pUp->Frm().Height();
1447 			nChg = Min( nDiff, nChg );
1448 
1449 			if ( !IsBodyFrm() )
1450 			{
1451 				SetCompletePaint();
1452 				if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->Frm().Height() )
1453 				{
1454 					//Ersteinmal den Body verkleinern. Der waechst dann schon
1455 					//wieder.
1456 					SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
1457 					const long nTmp = nChg - pBody->Prt().Height();
1458 					if ( !bTst )
1459 					{
1460 						pBody->Frm().Height(Max( 0L, pBody->Frm().Height() - nChg ));
1461 						pBody->_InvalidatePrt();
1462 						pBody->_InvalidateSize();
1463 						if ( pBody->GetNext() )
1464 							pBody->GetNext()->_InvalidatePos();
1465 						if ( !IsHeaderFrm() )
1466 							pBody->SetCompletePaint();
1467 					}
1468 					nChg = nTmp <= 0 ? 0 : nTmp;
1469 				}
1470 			}
1471 
1472 			const long nTmp = nUpPrtBottom + 20;
1473 			aInva.Top( aInva.Bottom() - nTmp );
1474 			aInva.Height( nChg + nTmp );
1475 		}
1476 		else
1477 		{
1478 			//Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt
1479 			//mindestens so gross wie die VisArea.
1480 			nChg = nDiff;
1481 			long nInvaAdd = 0;
1482 			if ( pViewShell && !pUp->GetPrev() &&
1483 				 pUp->Frm().Height() + nDiff < pViewShell->VisArea().Height() )
1484 			{
1485 				//Das heisst aber wiederum trotzdem, das wir geeignet invalidieren
1486 				//muessen.
1487 				nChg = pViewShell->VisArea().Height() - pUp->Frm().Height();
1488 				nInvaAdd = -(nDiff - nChg);
1489 			}
1490 
1491 			//Invalidieren inklusive unterem Rand.
1492 			long nBorder = nUpPrtBottom + 20;
1493 			nBorder -= nChg;
1494 			aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
1495 			if ( !IsBodyFrm() )
1496 			{
1497 				SetCompletePaint();
1498 				if ( !IsHeaderFrm() )
1499 					((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
1500 			}
1501 			//Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite
1502 			//wieder entsprechend gross wenn ein Rahmen nicht passt. Das
1503 			//funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen
1504 			//(NotifyFlys).
1505 			pUp->InvalidateSize();
1506 		}
1507 		if ( !bTst )
1508 		{
1509 			//Unabhaengig von nChg
1510 			if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
1511 				pViewShell->InvalidateWindows( aInva );
1512 		}
1513 		if ( !bTst && nChg )
1514 		{
1515 			const SwRect aOldRect( pUp->Frm() );
1516 			pUp->Frm().SSize().Height() += nChg;
1517 			pUp->Prt().SSize().Height() += nChg;
1518 			if ( pViewShell )
1519 				pViewShell->Imp()->SetFirstVisPageInvalid();
1520 
1521 			if ( GetNext() )
1522 				GetNext()->_InvalidatePos();
1523 
1524 			//Ggf. noch ein Repaint ausloesen.
1525 			const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
1526 			if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
1527 				pViewShell->InvalidateWindows( pUp->Frm() );
1528 
1529 			if ( pUp->GetUpper() )
1530 			{
1531 				if ( pUp->GetNext() )
1532 					pUp->GetNext()->InvalidatePos();
1533 
1534 				//Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc
1535 				//auf die Seite und deren Lower gerufen. Die Werte sollten
1536 				//unverandert bleiben, weil der Aufrufer bereits fuer die
1537 				//Anpassung von Frm und Prt sorgen wird.
1538 				const long nOldFrmHeight = Frm().Height();
1539 				const long nOldPrtHeight = Prt().Height();
1540 				const sal_Bool bOldComplete = IsCompletePaint();
1541 				if ( IsBodyFrm() )
1542 					Prt().SSize().Height() = nOldFrmHeight;
1543 
1544                 // PAGES01
1545                 if ( pUp->GetUpper() )
1546                     static_cast<SwRootFrm*>(pUp->GetUpper())->CheckViewLayout( 0, 0 );
1547                 //((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );
1548 
1549                 Frm().SSize().Height() = nOldFrmHeight;
1550 				Prt().SSize().Height() = nOldPrtHeight;
1551 				bCompletePaint = bOldComplete;
1552 			}
1553 			if ( !IsBodyFrm() )
1554 				pUp->_InvalidateSize();
1555 			InvalidatePage( (SwPageFrm*)pUp );
1556 		}
1557 		nDiff -= nChg;
1558 		if ( !nDiff )
1559 			return nChg;
1560 		else
1561 			nBrowseAdd = nChg;
1562 	}
1563 
1564 	const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
1565 
1566 	SwTwips nReal = 0,
1567 			nAdd  = 0;
1568 	SwFrm *pFrm = 0;
1569     SWRECTFN( this )
1570 
1571 	if( IsBodyFrm() )
1572 	{
1573 		if( IsInSct() )
1574 		{
1575 			SwSectionFrm *pSect = FindSctFrm();
1576 			if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
1577 				GetNext()->IsFtnContFrm() )
1578 			{
1579 				SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
1580 				SwTwips nMinH = 0;
1581 				SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
1582 				sal_Bool bFtn = sal_False;
1583 				while( pFtn )
1584 				{
1585 					if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
1586 					{
1587                         nMinH += (pFtn->Frm().*fnRect->fnGetHeight)();
1588 						bFtn = sal_True;
1589 					}
1590 					pFtn = (SwFtnFrm*)pFtn->GetNext();
1591 				}
1592 				if( bFtn )
1593                     nMinH += (pCont->Prt().*fnRect->fnGetTop)();
1594                 nReal = (pCont->Frm().*fnRect->fnGetHeight)() - nMinH;
1595 				if( nReal > nDiff )
1596 					nReal = nDiff;
1597 				if( nReal > 0 )
1598 					pFrm = GetNext();
1599 				else
1600 					nReal = 0;
1601 			}
1602 			if( !bTst && !pSect->IsColLocked() )
1603 				pSect->InvalidateSize();
1604 		}
1605 		if( !pFrm )
1606 			return nBrowseAdd;
1607 	}
1608 	else
1609 	{
1610 		const sal_Bool bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
1611 		if ( bFtnPage && !IsFtnContFrm() )
1612 			pFrm = (SwFrm*)pBoss->FindFtnCont();
1613 		if ( !pFrm )
1614 			pFrm = (SwFrm*)pBoss->FindBodyCont();
1615 
1616 		if ( !pFrm )
1617 			return 0;
1618 
1619 		//Wenn ich keinen finde eruebrigt sich alles weitere.
1620         nReal = (pFrm->Frm().*fnRect->fnGetHeight)();
1621         if( nReal > nDiff )
1622             nReal = nDiff;
1623 		if( !bFtnPage )
1624 		{
1625 			//Minimalgrenze beachten!
1626 			if( nReal )
1627 			{
1628 				const SwTwips nMax = pBoss->GetVarSpace();
1629 				if ( nReal > nMax )
1630 					nReal = nMax;
1631 			}
1632 			if( !IsFtnContFrm() && nDiff > nReal &&
1633                 pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm()
1634                 && ( pFrm->GetNext()->IsVertical() == IsVertical() )
1635                 )
1636 			{
1637 				//Wenn der Body nicht genuegend her gibt, kann ich noch mal
1638 				//schauen ob es eine Fussnote gibt, falls ja kann dieser
1639 				//entsprechend viel gemopst werden.
1640                 const SwTwips nAddMax = (pFrm->GetNext()->Frm().*fnRect->
1641                                         fnGetHeight)();
1642 				nAdd = nDiff - nReal;
1643 				if ( nAdd > nAddMax )
1644 					nAdd = nAddMax;
1645 				if ( !bTst )
1646 				{
1647                     (pFrm->GetNext()->Frm().*fnRect->fnSetHeight)(nAddMax-nAdd);
1648                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1649                     if( bVert && !bVertL2R && !bRev )
1650                         pFrm->GetNext()->Frm().Pos().X() += nAdd;
1651 					pFrm->GetNext()->InvalidatePrt();
1652 					if ( pFrm->GetNext()->GetNext() )
1653 						pFrm->GetNext()->GetNext()->_InvalidatePos();
1654 				}
1655 			}
1656 		}
1657 	}
1658 
1659 	if ( !bTst && nReal )
1660 	{
1661         SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)();
1662         (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal );
1663         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1664         if( bVert && !bVertL2R && !bRev )
1665             pFrm->Frm().Pos().X() += nReal;
1666 		pFrm->InvalidatePrt();
1667 		if ( pFrm->GetNext() )
1668 			pFrm->GetNext()->_InvalidatePos();
1669 		if( nReal < 0 && pFrm->IsInSct() )
1670 		{
1671 			SwLayoutFrm* pUp = pFrm->GetUpper();
1672 			if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
1673 				!pUp->IsColLocked() )
1674 				pUp->InvalidateSize();
1675 		}
1676 		if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
1677 		{
1678             const SwSortedObjs &rObjs = *pBoss->GetDrawObjs();
1679 			ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" );
1680             for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1681 			{
1682                 SwAnchoredObject* pAnchoredObj = rObjs[i];
1683                 if ( pAnchoredObj->ISA(SwFlyFrm) )
1684 				{
1685                     SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1686 					ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
1687 					const SwFmtVertOrient &rVert =
1688 										pFly->GetFmt()->GetVertOrient();
1689 				   // Wann muss invalidiert werden?
1690 				   // Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist,
1691 				   // muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE,
1692 				   // bei Aenderung des Footers ein BOTTOM oder MIDDLE
1693 				   // ausgerichteter Rahmen seine Position neu berechnen.
1694                     if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
1695                           rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )    &&
1696                         ((IsHeaderFrm() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
1697                          (IsFooterFrm() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
1698                           rVert.GetVertOrient() != text::VertOrientation::TOP)) )
1699 					{
1700 						pFly->_InvalidatePos();
1701 						pFly->_Invalidate();
1702 					}
1703 				}
1704 			}
1705 		}
1706 	}
1707 	return (nBrowseAdd + nReal + nAdd);
1708 }
1709 
1710 /*************************************************************************
1711 |*
1712 |*	SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(),
1713 |* 		   ImplInvalidateLineNum()
1714 |*
1715 |*	Ersterstellung		MA 15. Oct. 92
1716 |*	Letzte Aenderung	MA 24. Mar. 94
1717 |*
1718 |*************************************************************************/
1719 /** method to perform additional actions on an invalidation
1720 
1721     OD 2004-05-19 #i28701#
1722 
1723     @author OD
1724 */
1725 void SwFrm::_ActionOnInvalidation( const InvalidationType )
1726 {
1727     // default behaviour is to perform no additional action
1728 }
1729 
1730 /** method to determine, if an invalidation is allowed.
1731 
1732     OD 2004-05-19 #i28701#
1733 
1734     @author OD
1735 */
1736 bool SwFrm::_InvalidationAllowed( const InvalidationType ) const
1737 {
1738     // default behaviour is to allow invalidation
1739     return true;
1740 }
1741 
1742 void SwFrm::ImplInvalidateSize()
1743 {
1744     if ( _InvalidationAllowed( INVALID_SIZE ) )
1745     {
1746         bValidSize = sal_False;
1747         if ( IsFlyFrm() )
1748             ((SwFlyFrm*)this)->_Invalidate();
1749         else
1750             InvalidatePage();
1751 
1752         // OD 2004-05-19 #i28701#
1753         _ActionOnInvalidation( INVALID_SIZE );
1754     }
1755 }
1756 
1757 void SwFrm::ImplInvalidatePrt()
1758 {
1759     if ( _InvalidationAllowed( INVALID_PRTAREA ) )
1760     {
1761         bValidPrtArea = sal_False;
1762         if ( IsFlyFrm() )
1763             ((SwFlyFrm*)this)->_Invalidate();
1764         else
1765             InvalidatePage();
1766 
1767         // OD 2004-05-19 #i28701#
1768         _ActionOnInvalidation( INVALID_PRTAREA );
1769     }
1770 }
1771 
1772 void SwFrm::ImplInvalidatePos()
1773 {
1774     if ( _InvalidationAllowed( INVALID_POS ) )
1775     {
1776         bValidPos = sal_False;
1777         if ( IsFlyFrm() )
1778         {
1779             ((SwFlyFrm*)this)->_Invalidate();
1780         }
1781         else
1782         {
1783             InvalidatePage();
1784         }
1785 
1786         // OD 2004-05-19 #i28701#
1787         _ActionOnInvalidation( INVALID_POS );
1788     }
1789 }
1790 
1791 void SwFrm::ImplInvalidateLineNum()
1792 {
1793     if ( _InvalidationAllowed( INVALID_LINENUM ) )
1794     {
1795         bValidLineNum = sal_False;
1796         ASSERT( IsTxtFrm(), "line numbers are implemented for text only" );
1797         InvalidatePage();
1798 
1799         // OD 2004-05-19 #i28701#
1800         _ActionOnInvalidation( INVALID_LINENUM );
1801     }
1802 }
1803 
1804 /*************************************************************************
1805 |*
1806 |*	SwFrm::ReinitializeFrmSizeAttrFlags
1807 |*
1808 |*	Ersterstellung		MA 15. Oct. 96
1809 |*	Letzte Aenderung	MA 15. Oct. 96
1810 |*
1811 |*************************************************************************/
1812 void SwFrm::ReinitializeFrmSizeAttrFlags()
1813 {
1814 	const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
1815     if ( ATT_VAR_SIZE == rFmtSize.GetHeightSizeType() ||
1816          ATT_MIN_SIZE == rFmtSize.GetHeightSizeType())
1817 	{
1818         bFixSize = sal_False;
1819 		if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
1820 		{
1821 			SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
1822 			while ( pFrm )
1823 			{	pFrm->_InvalidateSize();
1824 				pFrm->_InvalidatePrt();
1825 				pFrm = pFrm->GetNext();
1826 			}
1827 			SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
1828             // --> OD 2004-12-20 #i36991# - be save.
1829             // E.g., a row can contain *no* content.
1830             if ( pCnt )
1831             {
1832                 pCnt->InvalidatePage();
1833                 do
1834                 {
1835                     pCnt->Prepare( PREP_ADJUST_FRM );
1836                     pCnt->_InvalidateSize();
1837                     pCnt = pCnt->GetNextCntntFrm();
1838                 } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
1839             }
1840             // <--
1841 		}
1842 	}
1843     else if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
1844     {
1845         if( IsVertical() )
1846 			ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
1847         else
1848 			ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
1849 	}
1850 }
1851 
1852 /*************************************************************************
1853 |*  SwFrm::ValidateThisAndAllLowers()
1854  *
1855  * FME 2007-08-30 #i81146# new loop control
1856 |*************************************************************************/
1857 void SwFrm::ValidateThisAndAllLowers( const sal_uInt16 nStage )
1858 {
1859     // Stage 0: Only validate frames. Do not process any objects.
1860     // Stage 1: Only validate fly frames and all of their contents.
1861     // Stage 2: Validate all.
1862 
1863     const bool bOnlyObject = 1 == nStage;
1864     const bool bIncludeObjects = 1 <= nStage;
1865 
1866     if ( !bOnlyObject || ISA(SwFlyFrm) )
1867     {
1868         bValidSize = sal_True;
1869         bValidPrtArea = sal_True;
1870         bValidPos = sal_True;
1871     }
1872 
1873     if ( bIncludeObjects )
1874     {
1875         const SwSortedObjs* pObjs = GetDrawObjs();
1876         if ( pObjs )
1877         {
1878             const sal_uInt32 nCnt = pObjs->Count();
1879             for ( sal_uInt32 i = 0; i < nCnt; ++i )
1880             {
1881                 SwAnchoredObject* pAnchObj = (*pObjs)[i];
1882                 if ( pAnchObj->ISA(SwFlyFrm) )
1883                     static_cast<SwFlyFrm*>(pAnchObj)->ValidateThisAndAllLowers( 2 );
1884                 else if ( pAnchObj->ISA(SwAnchoredDrawObject) )
1885                     static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis();
1886             }
1887         }
1888     }
1889 
1890     if ( IsLayoutFrm() )
1891     {
1892         SwFrm* pLower = static_cast<SwLayoutFrm*>(this)->Lower();
1893         while ( pLower )
1894         {
1895             pLower->ValidateThisAndAllLowers( nStage );
1896             pLower = pLower->GetNext();
1897         }
1898     }
1899 }
1900 
1901 /*************************************************************************
1902 |*
1903 |*	SwCntntFrm::GrowFrm()
1904 |*
1905 |*	Ersterstellung		MA 30. Jul. 92
1906 |*	Letzte Aenderung	MA 25. Mar. 99
1907 |*
1908 |*************************************************************************/
1909 SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1910 {
1911     SWRECTFN( this )
1912 
1913     SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1914     if( nFrmHeight > 0 &&
1915          nDist > (LONG_MAX - nFrmHeight ) )
1916         nDist = LONG_MAX - nFrmHeight;
1917 
1918     const ViewShell *pSh = getRootFrm()->GetCurrShell();
1919     const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1920     const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
1921     if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
1922 	{
1923 		if ( !bTst )
1924 		{
1925             (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
1926             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1927             if( IsVertical() && !IsVertLR() && !IsReverse() )
1928                 Frm().Pos().X() -= nDist;
1929 			if ( GetNext() )
1930             {
1931 				GetNext()->InvalidatePos();
1932             }
1933             // --> OD 2004-07-05 #i28701# - Due to the new object positioning the
1934             // frame on the next page/column can flow backward (e.g. it was moved forward
1935             // due to the positioning of its objects ). Thus, invalivate this next frame,
1936             // if document compatibility option 'Consider wrapping style influence on
1937             // object positioning' is ON.
1938             else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1939             {
1940                 InvalidateNextPos();
1941             }
1942             // <--
1943 		}
1944 		return 0;
1945 	}
1946 
1947     SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)();
1948 	SwFrm *pFrm = GetUpper()->Lower();
1949     while( pFrm && nReal > 0 )
1950     {   nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
1951 		pFrm = pFrm->GetNext();
1952 	}
1953 
1954 	if ( !bTst )
1955 	{
1956 		//Cntnts werden immer auf den gewuenschten Wert gebracht.
1957         long nOld = (Frm().*fnRect->fnGetHeight)();
1958         (Frm().*fnRect->fnSetHeight)( nOld + nDist );
1959         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1960         if( IsVertical()&& !IsVertLR() && !IsReverse() )
1961             Frm().Pos().X() -= nDist;
1962 		if ( nOld && IsInTab() )
1963 		{
1964 			SwTabFrm *pTab = FindTabFrm();
1965 			if ( pTab->GetTable()->GetHTMLTableLayout() &&
1966 				 !pTab->IsJoinLocked() &&
1967 				 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
1968 			{
1969 				pTab->InvalidatePos();
1970 				pTab->SetResizeHTMLTable();
1971 			}
1972 		}
1973 	}
1974 
1975 	//Upper nur growen wenn notwendig.
1976 	if ( nReal < nDist )
1977     {
1978         if( GetUpper() )
1979         {
1980             if( bTst || !GetUpper()->IsFooterFrm() )
1981                 nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
1982                                           bTst, bInfo );
1983             else
1984             {
1985                 nReal = 0;
1986                 GetUpper()->InvalidateSize();
1987             }
1988         }
1989         else
1990             nReal = 0;
1991     }
1992     else
1993 		nReal = nDist;
1994 
1995     // --> OD 2004-07-05 #i28701# - Due to the new object positioning the
1996     // frame on the next page/column can flow backward (e.g. it was moved forward
1997     // due to the positioning of its objects ). Thus, invalivate this next frame,
1998     // if document compatibility option 'Consider wrapping style influence on
1999     // object positioning' is ON.
2000     if ( !bTst )
2001     {
2002         if ( GetNext() )
2003         {
2004             GetNext()->InvalidatePos();
2005         }
2006         else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2007         {
2008             InvalidateNextPos();
2009         }
2010     }
2011     // <--
2012 
2013 	return nReal;
2014 }
2015 
2016 /*************************************************************************
2017 |*
2018 |*	SwCntntFrm::ShrinkFrm()
2019 |*
2020 |*	Ersterstellung		MA 30. Jul. 92
2021 |*	Letzte Aenderung	MA 05. May. 94
2022 |*
2023 |*************************************************************************/
2024 SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2025 {
2026     SWRECTFN( this )
2027 	ASSERT( nDist >= 0, "nDist < 0" );
2028     ASSERT( nDist <= (Frm().*fnRect->fnGetHeight)(),
2029 			"nDist > als aktuelle Grosse." );
2030 
2031 	if ( !bTst )
2032 	{
2033         SwTwips nRstHeight;
2034         if( GetUpper() )
2035             nRstHeight = (Frm().*fnRect->fnBottomDist)
2036                          ( (GetUpper()->*fnRect->fnGetPrtBottom)() );
2037         else
2038             nRstHeight = 0;
2039 		if( nRstHeight < 0 )
2040         {
2041             SwTwips nNextHeight = 0;
2042             if( GetUpper()->IsSctFrm() && nDist > LONG_MAX/2 )
2043             {
2044                 SwFrm *pNxt = GetNext();
2045                 while( pNxt )
2046                 {
2047                     nNextHeight += (pNxt->Frm().*fnRect->fnGetHeight)();
2048                     pNxt = pNxt->GetNext();
2049                 }
2050             }
2051             nRstHeight = nDist + nRstHeight - nNextHeight;
2052         }
2053         else
2054 			nRstHeight = nDist;
2055         (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist );
2056         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2057         if( IsVertical() && !IsVertLR() )
2058             Frm().Pos().X() += nDist;
2059 		nDist = nRstHeight;
2060 		if ( IsInTab() )
2061 		{
2062 			SwTabFrm *pTab = FindTabFrm();
2063 			if ( pTab->GetTable()->GetHTMLTableLayout() &&
2064 				 !pTab->IsJoinLocked() &&
2065 				 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
2066 			{
2067 				pTab->InvalidatePos();
2068 				pTab->SetResizeHTMLTable();
2069 			}
2070 		}
2071 	}
2072 
2073     SwTwips nReal;
2074     if( GetUpper() && nDist > 0 )
2075     {
2076         if( bTst || !GetUpper()->IsFooterFrm() )
2077             nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
2078         else
2079         {
2080             nReal = 0;
2081 
2082             // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
2083             // if there are any objects anchored inside your content, which
2084             // overlap with the shrinking frame.
2085             // This may lead to a footer frame that is too big, but this is better
2086             // than looping.
2087             // #109722# : The fix for #108745# was too strict.
2088 
2089             bool bInvalidate = true;
2090             const SwRect aRect( Frm() );
2091             const SwPageFrm* pPage = FindPageFrm();
2092             const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : 0;
2093             if( pSorted )
2094             {
2095                 for ( sal_uInt16 i = 0; i < pSorted->Count(); ++i )
2096                 {
2097                     const SwAnchoredObject* pAnchoredObj = (*pSorted)[i];
2098                     const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
2099 
2100                     if( aBound.Left() > aRect.Right() )
2101                         continue;
2102 
2103                     if( aBound.IsOver( aRect ) )
2104                     {
2105                         const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
2106                         if( SURROUND_THROUGHT != rFmt.GetSurround().GetSurround() )
2107                         {
2108                             const SwFrm* pAnchor = pAnchoredObj->GetAnchorFrm();
2109                             if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
2110                             {
2111                                 bInvalidate = false;
2112                                 break;
2113                             }
2114                         }
2115                     }
2116                 }
2117             }
2118 
2119             if ( bInvalidate )
2120                 GetUpper()->InvalidateSize();
2121         }
2122     }
2123     else
2124         nReal = 0;
2125 
2126 	if ( !bTst )
2127 	{
2128 		//Die Position des naechsten Frm's veraendert sich auf jeden Fall.
2129 		InvalidateNextPos();
2130 
2131         //Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um
2132 		//die Retusche kuemmern.
2133 		if ( !GetNext() )
2134 			SetRetouche();
2135 	}
2136 	return nReal;
2137 }
2138 
2139 /*************************************************************************
2140 |*
2141 |*	  SwCntntFrm::Modify()
2142 |*
2143 |*	  Beschreibung
2144 |*	  Ersterstellung	AK 05-Mar-1991
2145 |*	  Letzte Aenderung	MA 13. Oct. 95
2146 |*
2147 |*************************************************************************/
2148 void SwCntntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
2149 {
2150 	sal_uInt8 nInvFlags = 0;
2151 
2152 	if( pNew && RES_ATTRSET_CHG == pNew->Which() )
2153 	{
2154 		SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
2155 		SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
2156 		SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
2157 		SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
2158 		while( sal_True )
2159 		{
2160 			_UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
2161 						 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
2162 						 &aOldSet, &aNewSet );
2163 			if( aNIter.IsAtEnd() )
2164 				break;
2165 			aNIter.NextItem();
2166 			aOIter.NextItem();
2167 		}
2168 		if ( aOldSet.Count() || aNewSet.Count() )
2169 			SwFrm::Modify( &aOldSet, &aNewSet );
2170 	}
2171 	else
2172 		_UpdateAttr( pOld, pNew, nInvFlags );
2173 
2174 	if ( nInvFlags != 0 )
2175 	{
2176 		SwPageFrm *pPage = FindPageFrm();
2177 		InvalidatePage( pPage );
2178 		if ( nInvFlags & 0x01 )
2179 			SetCompletePaint();
2180 		if ( nInvFlags & 0x02 )
2181 			_InvalidatePos();
2182 		if ( nInvFlags & 0x04 )
2183 			_InvalidateSize();
2184 		if ( nInvFlags & 0x88 )
2185 		{
2186 			if( IsInSct() && !GetPrev() )
2187 			{
2188 				SwSectionFrm *pSect = FindSctFrm();
2189 				if( pSect->ContainsAny() == this )
2190 				{
2191 					pSect->_InvalidatePrt();
2192 					pSect->InvalidatePage( pPage );
2193 				}
2194 			}
2195 			_InvalidatePrt();
2196 		}
2197         SwFrm* pNextFrm = GetIndNext();
2198         if ( pNextFrm && nInvFlags & 0x10)
2199 		{
2200             pNextFrm->_InvalidatePrt();
2201             pNextFrm->InvalidatePage( pPage );
2202 		}
2203         if ( pNextFrm && nInvFlags & 0x80 )
2204         {
2205             pNextFrm->SetCompletePaint();
2206         }
2207         if ( nInvFlags & 0x20 )
2208 		{
2209             SwFrm* pPrevFrm = GetPrev();
2210             if ( pPrevFrm )
2211             {
2212                 pPrevFrm->_InvalidatePrt();
2213                 pPrevFrm->InvalidatePage( pPage );
2214             }
2215 		}
2216 		if ( nInvFlags & 0x40 )
2217 			InvalidateNextPos();
2218 	}
2219 }
2220 
2221 void SwCntntFrm::_UpdateAttr( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
2222 							  sal_uInt8 &rInvFlags,
2223 							SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2224 {
2225 	sal_Bool bClear = sal_True;
2226 	sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2227 	switch ( nWhich )
2228 	{
2229 		case RES_FMT_CHG:
2230 			rInvFlags = 0xFF;
2231 			/* kein break hier */
2232 
2233 		case RES_PAGEDESC:						//Attributaenderung (an/aus)
2234 			if ( IsInDocBody() && !IsInTab() )
2235 			{
2236 				rInvFlags |= 0x02;
2237 				SwPageFrm *pPage = FindPageFrm();
2238 				if ( !GetPrev() )
2239 					CheckPageDescs( pPage );
2240 				if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() )
2241 					((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( sal_True );
2242 				SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
2243 				pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
2244 			}
2245 			break;
2246 
2247 		case RES_UL_SPACE:
2248 			{
2249                 // OD 2004-02-18 #106629# - correction
2250                 // Invalidation of the printing area of next frame, not only
2251                 // for footnote content.
2252                 if ( !GetIndNext() )
2253 				{
2254 					SwFrm* pNxt = FindNext();
2255                     if ( pNxt )
2256 					{
2257 						SwPageFrm* pPg = pNxt->FindPageFrm();
2258 						pNxt->InvalidatePage( pPg );
2259 						pNxt->_InvalidatePrt();
2260 						if( pNxt->IsSctFrm() )
2261 						{
2262 							SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2263 							if( pCnt )
2264 							{
2265 								pCnt->_InvalidatePrt();
2266 								pCnt->InvalidatePage( pPg );
2267 							}
2268 						}
2269 						pNxt->SetCompletePaint();
2270                     }
2271 				}
2272                 // OD 2004-03-17 #i11860#
2273                 if ( GetIndNext() &&
2274                      !GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
2275                 {
2276                     // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
2277                     GetIndNext()->InvalidateObjs( true );
2278                 }
2279                 Prepare( PREP_UL_SPACE );   //TxtFrm muss Zeilenabst. korrigieren.
2280 				rInvFlags |= 0x80;
2281 				/* kein Break hier */
2282 			}
2283 		case RES_LR_SPACE:
2284 		case RES_BOX:
2285 		case RES_SHADOW:
2286 			Prepare( PREP_FIXSIZE_CHG );
2287 			SwFrm::Modify( pOld, pNew );
2288 			rInvFlags |= 0x30;
2289 			break;
2290 
2291 		case RES_BREAK:
2292 			{
2293 				rInvFlags |= 0x42;
2294                 const IDocumentSettingAccess* pIDSA = GetUpper()->GetFmt()->getIDocumentSettingAccess();
2295                 if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
2296                     pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) )
2297 				{
2298 					rInvFlags |= 0x1;
2299 					SwFrm* pNxt = FindNext();
2300 					if( pNxt )
2301 					{
2302 						SwPageFrm* pPg = pNxt->FindPageFrm();
2303 						pNxt->InvalidatePage( pPg );
2304 						pNxt->_InvalidatePrt();
2305 						if( pNxt->IsSctFrm() )
2306 						{
2307 							SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2308 							if( pCnt )
2309 							{
2310 								pCnt->_InvalidatePrt();
2311 								pCnt->InvalidatePage( pPg );
2312 							}
2313 						}
2314 						pNxt->SetCompletePaint();
2315 					}
2316 				}
2317 			}
2318 			break;
2319 
2320         // OD 2004-02-26 #i25029#
2321         case RES_PARATR_CONNECT_BORDER:
2322         {
2323             rInvFlags |= 0x01;
2324             if ( IsTxtFrm() )
2325             {
2326                 InvalidateNextPrtArea();
2327             }
2328             if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
2329             {
2330                 FindTabFrm()->InvalidateSize();
2331             }
2332         }
2333         break;
2334 
2335 		case RES_PARATR_TABSTOP:
2336 		case RES_CHRATR_PROPORTIONALFONTSIZE:
2337 		case RES_CHRATR_SHADOWED:
2338 		case RES_CHRATR_AUTOKERN:
2339 		case RES_CHRATR_UNDERLINE:
2340 		case RES_CHRATR_OVERLINE:
2341 		case RES_CHRATR_KERNING:
2342 		case RES_CHRATR_FONT:
2343 		case RES_CHRATR_FONTSIZE:
2344 		case RES_CHRATR_ESCAPEMENT:
2345 		case RES_CHRATR_CONTOUR:
2346         case RES_PARATR_NUMRULE:
2347 			rInvFlags |= 0x01;
2348 			break;
2349 
2350 
2351 		case RES_FRM_SIZE:
2352 			rInvFlags |= 0x01;
2353 			/* no break here */
2354 
2355 		default:
2356 			bClear = sal_False;
2357 	}
2358 	if ( bClear )
2359 	{
2360 		if ( pOldSet || pNewSet )
2361 		{
2362 			if ( pOldSet )
2363 				pOldSet->ClearItem( nWhich );
2364 			if ( pNewSet )
2365 				pNewSet->ClearItem( nWhich );
2366 		}
2367 		else
2368 			SwFrm::Modify( pOld, pNew );
2369 	}
2370 }
2371 
2372 /*************************************************************************
2373 |*
2374 |*	SwLayoutFrm::SwLayoutFrm()
2375 |*
2376 |*	Ersterstellung		AK 14-Feb-1991
2377 |*	Letzte Aenderung	MA 12. May. 95
2378 |*
2379 |*************************************************************************/
2380 SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt, SwFrm* pSib ):
2381 	SwFrm( pFmt, pSib ),
2382     pLower( 0 )
2383 {
2384 	const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
2385     if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
2386         bFixSize = sal_True;
2387 }
2388 
2389 // --> OD 2004-06-29 #i28701#
2390 TYPEINIT1(SwLayoutFrm,SwFrm);
2391 // <--
2392 /*-----------------10.06.99 09:42-------------------
2393  * SwLayoutFrm::InnerHeight()
2394  * --------------------------------------------------*/
2395 
2396 SwTwips SwLayoutFrm::InnerHeight() const
2397 {
2398 	if( !Lower() )
2399 		return 0;
2400 	SwTwips nRet = 0;
2401 	const SwFrm* pCnt = Lower();
2402     SWRECTFN( this )
2403 	if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
2404 	{
2405 		do
2406 		{
2407 			SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight();
2408 			if( pCnt->GetValidPrtAreaFlag() )
2409                 nTmp += (pCnt->Frm().*fnRect->fnGetHeight)() -
2410                         (pCnt->Prt().*fnRect->fnGetHeight)();
2411             if( nRet < nTmp )
2412 				nRet = nTmp;
2413 			pCnt = pCnt->GetNext();
2414 		} while ( pCnt );
2415 	}
2416 	else
2417 	{
2418 		do
2419 		{
2420             nRet += (pCnt->Frm().*fnRect->fnGetHeight)();
2421 			if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
2422                 nRet += ((SwTxtFrm*)pCnt)->GetParHeight() -
2423                         (pCnt->Prt().*fnRect->fnGetHeight)();
2424 			if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
2425                 nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() -
2426                         (pCnt->Prt().*fnRect->fnGetHeight)();
2427 			pCnt = pCnt->GetNext();
2428 		} while( pCnt );
2429 
2430 	}
2431 	return nRet;
2432 }
2433 
2434 /*************************************************************************
2435 |*
2436 |*	SwLayoutFrm::GrowFrm()
2437 |*
2438 |*	Ersterstellung		MA 30. Jul. 92
2439 |*	Letzte Aenderung	MA 23. Sep. 96
2440 |*
2441 |*************************************************************************/
2442 SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2443 {
2444     const ViewShell *pSh = getRootFrm()->GetCurrShell();
2445     const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2446     const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
2447     if( !(GetType() & nTmpType) && HasFixSize() )
2448 		return 0;
2449 
2450     SWRECTFN( this )
2451     const SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2452     const SwTwips nFrmPos = Frm().Pos().X();
2453 
2454     if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
2455         nDist = LONG_MAX - nFrmHeight;
2456 
2457     SwTwips nMin = 0;
2458     if ( GetUpper() && !IsCellFrm() )
2459 	{
2460         SwFrm *pFrm = GetUpper()->Lower();
2461         while( pFrm )
2462         {   nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2463             pFrm = pFrm->GetNext();
2464         }
2465         nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin;
2466 		if ( nMin < 0 )
2467 			nMin = 0;
2468 	}
2469 
2470 	SwRect aOldFrm( Frm() );
2471 	sal_Bool bMoveAccFrm = sal_False;
2472 
2473     sal_Bool bChgPos = IsVertical() && !IsReverse();
2474 	if ( !bTst )
2475     {
2476         (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
2477         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2478         if( bChgPos && !IsVertLR() )
2479             Frm().Pos().X() -= nDist;
2480 		bMoveAccFrm = sal_True;
2481     }
2482 
2483 	SwTwips nReal = nDist - nMin;
2484 	if ( nReal > 0 )
2485 	{
2486 		if ( GetUpper() )
2487 		{   // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen)
2488 			sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
2489 				((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2490 				: NA_GROW_SHRINK;
2491 			if( NA_ONLY_ADJUST == nAdjust )
2492 				nReal = AdjustNeighbourhood( nReal, bTst );
2493 			else
2494 			{
2495 				if( NA_ADJUST_GROW == nAdjust )
2496 					nReal += AdjustNeighbourhood( nReal, bTst );
2497 
2498                 SwTwips nGrow = 0;
2499 				if( 0 < nReal )
2500                 {
2501                     SwFrm* pToGrow = GetUpper();
2502                     // NEW TABLES
2503                     // A cell with a row span of > 1 is allowed to grow the
2504                     // line containing the end of the row span if it is
2505                     // located in the same table frame:
2506                     const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2507                     if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2508                     {
2509                         SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2510                         if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
2511                             pToGrow = rEndCell.GetUpper();
2512                         else
2513                             pToGrow = 0;
2514                     }
2515 
2516                     nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
2517                 }
2518 
2519 				if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
2520 					nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
2521 
2522                 if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
2523 				{
2524 					//Fussnoten koennen ihre Nachfolger verdraengen.
2525 					SwTwips nSpace = bTst ? 0 : -nDist;
2526 					const SwFrm *pFrm = GetUpper()->Lower();
2527 					do
2528                     {   nSpace += (pFrm->Frm().*fnRect->fnGetHeight)();
2529 						pFrm = pFrm->GetNext();
2530 					} while ( pFrm != GetNext() );
2531                     nSpace = (GetUpper()->Prt().*fnRect->fnGetHeight)() -nSpace;
2532 					if ( nSpace < 0 )
2533 						nSpace = 0;
2534 					nSpace += nGrow;
2535 					if ( nReal > nSpace )
2536 						nReal = nSpace;
2537 					if ( nReal && !bTst )
2538 						((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() );
2539 				}
2540 				else
2541 					nReal = nGrow;
2542 			}
2543 		}
2544 		else
2545 			nReal = 0;
2546 
2547 		nReal += nMin;
2548 	}
2549 	else
2550 		nReal = nDist;
2551 
2552 	if ( !bTst )
2553 	{
2554         if( nReal != nDist &&
2555             // NEW TABLES
2556             ( !IsCellFrm() || static_cast<SwCellFrm*>(this)->GetLayoutRowSpan() > 1 ) )
2557         {
2558             (Frm().*fnRect->fnSetHeight)( nFrmHeight + nReal );
2559             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2560             if( bChgPos && !IsVertLR() )
2561                 Frm().Pos().X() = nFrmPos - nReal;
2562 			bMoveAccFrm = sal_True;
2563         }
2564 
2565 		if ( nReal )
2566 		{
2567 			SwPageFrm *pPage = FindPageFrm();
2568 			if ( GetNext() )
2569 			{
2570 				GetNext()->_InvalidatePos();
2571 				if ( GetNext()->IsCntntFrm() )
2572 					GetNext()->InvalidatePage( pPage );
2573 			}
2574 			if ( !IsPageBodyFrm() )
2575 			{
2576 				_InvalidateAll();
2577 				InvalidatePage( pPage );
2578 			}
2579 			if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2580                 NotifyLowerObjs();
2581 
2582 			if( IsCellFrm() )
2583                 InvaPercentLowers( nReal );
2584 
2585 			const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2586 			if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2587 				SetCompletePaint();
2588 		}
2589 	}
2590 
2591 	if( bMoveAccFrm && IsAccessibleFrm() )
2592 	{
2593 		SwRootFrm *pRootFrm = getRootFrm();
2594 		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2595 			pRootFrm->GetCurrShell() )
2596 		{
2597 			pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2598 		}
2599 	}
2600 	return nReal;
2601 }
2602 
2603 /*************************************************************************
2604 |*
2605 |*	SwLayoutFrm::ShrinkFrm()
2606 |*
2607 |*	Ersterstellung		MA 30. Jul. 92
2608 |*	Letzte Aenderung	MA 25. Mar. 99
2609 |*
2610 |*************************************************************************/
2611 SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2612 {
2613     const ViewShell *pSh = getRootFrm()->GetCurrShell();
2614     const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2615     const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
2616     if( !(GetType() & nTmpType) && HasFixSize() )
2617 		return 0;
2618 
2619 	ASSERT( nDist >= 0, "nDist < 0" );
2620     SWRECTFN( this )
2621     SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2622     if ( nDist > nFrmHeight )
2623         nDist = nFrmHeight;
2624 
2625 	SwTwips nMin = 0;
2626     sal_Bool bChgPos = IsVertical() && !IsReverse();
2627 	if ( Lower() )
2628 	{
2629         if( !Lower()->IsNeighbourFrm() )
2630         {   const SwFrm *pFrm = Lower();
2631             const long nTmp = (Prt().*fnRect->fnGetHeight)();
2632             while( pFrm && nMin < nTmp )
2633             {   nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2634 				pFrm = pFrm->GetNext();
2635 			}
2636 		}
2637 	}
2638 	SwTwips nReal = nDist;
2639     SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin;
2640     if( nReal > nMinDiff )
2641         nReal = nMinDiff;
2642     if( nReal <= 0 )
2643 		return nDist;
2644 
2645 	SwRect aOldFrm( Frm() );
2646 	sal_Bool bMoveAccFrm = sal_False;
2647 
2648 	SwTwips nRealDist = nReal;
2649 	if ( !bTst )
2650     {
2651         (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal );
2652         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2653         if( bChgPos && !IsVertLR() )
2654         	Frm().Pos().X() += nReal;
2655 		bMoveAccFrm = sal_True;
2656     }
2657 
2658 	sal_uInt8 nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
2659 				   ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2660 				   : NA_GROW_SHRINK;
2661 
2662 	// AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen)
2663 	if( NA_ONLY_ADJUST == nAdjust )
2664 	{
2665 		if ( IsPageBodyFrm() && !bBrowse )
2666 			nReal = nDist;
2667 		else
2668 		{	nReal = AdjustNeighbourhood( -nReal, bTst );
2669 			nReal *= -1;
2670 			if ( !bTst && IsBodyFrm() && nReal < nRealDist )
2671             {
2672                 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2673                                             + nRealDist - nReal );
2674                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2675                 if( bChgPos && !IsVertLR() )
2676                     Frm().Pos().X() += nRealDist - nReal;
2677 				ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2678             }
2679 		}
2680 	}
2681     else if( IsColumnFrm() || IsColBodyFrm() )
2682     {
2683         SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
2684 		if ( nTmp != nReal )
2685 		{
2686             (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2687                                           + nReal - nTmp );
2688             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2689             if( bChgPos && !IsVertLR() )
2690                 Frm().Pos().X() += nTmp - nReal;
2691 			ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2692 			nReal = nTmp;
2693 		}
2694 	}
2695 	else
2696 	{
2697 		SwTwips nShrink = nReal;
2698         SwFrm* pToShrink = GetUpper();
2699         const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2700         // NEW TABLES
2701         if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2702         {
2703             SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2704             pToShrink = rEndCell.GetUpper();
2705         }
2706 
2707         nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
2708 		if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
2709 			&& nReal < nShrink )
2710 			AdjustNeighbourhood( nReal - nShrink );
2711 	}
2712 
2713 	if( bMoveAccFrm && IsAccessibleFrm() )
2714 	{
2715 		SwRootFrm *pRootFrm = getRootFrm();
2716 		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2717 			pRootFrm->GetCurrShell() )
2718 		{
2719 			pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2720 		}
2721 	}
2722 	if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
2723 	{
2724 		SwPageFrm *pPage = FindPageFrm();
2725 		if ( GetNext() )
2726 		{
2727 			GetNext()->_InvalidatePos();
2728 			if ( GetNext()->IsCntntFrm() )
2729 				GetNext()->InvalidatePage( pPage );
2730 			if ( IsTabFrm() )
2731 				((SwTabFrm*)this)->SetComplete();
2732 		}
2733 		else
2734 		{	if ( IsRetoucheFrm() )
2735 				SetRetouche();
2736 			if ( IsTabFrm() )
2737 			{
2738 				if( IsTabFrm() )
2739 					((SwTabFrm*)this)->SetComplete();
2740 				if ( Lower() ) 	//Kann auch im Join stehen und leer sein!
2741 					InvalidateNextPos();
2742 			}
2743 		}
2744 		if ( !IsBodyFrm() )
2745 		{
2746 			_InvalidateAll();
2747 			InvalidatePage( pPage );
2748 			const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2749 			if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2750 				SetCompletePaint();
2751 		}
2752 
2753 		if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2754             NotifyLowerObjs();
2755 
2756 		if( IsCellFrm() )
2757             InvaPercentLowers( nReal );
2758 
2759 		SwCntntFrm *pCnt;
2760 		if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
2761 			( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
2762               ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) &&
2763               0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) )
2764 		{
2765 			if ( pCnt->IsFollow() )
2766 			{   // Wenn wir sowieso schon in einer anderen Spalte/Seite sitzen
2767 				// als der Frame mit der Referenz, dann brauchen wir nicht
2768 				// auch noch seinen Master zu invalidieren.
2769 				SwFrm *pTmp = pCnt->FindFtnBossFrm(sal_True) == FindFtnBossFrm(sal_True)
2770 							  ?  pCnt->FindMaster()->GetFrm() : pCnt;
2771 				pTmp->Prepare( PREP_ADJUST_FRM );
2772 				pTmp->InvalidateSize();
2773 			}
2774 			else
2775 				pCnt->InvalidatePos();
2776 		}
2777 	}
2778 	return nReal;
2779 }
2780 /*************************************************************************
2781 |*
2782 |*	SwLayoutFrm::ChgLowersProp()
2783 |*
2784 |*	Beschreibung		Aendert die Grosse der direkt untergeordneten Frm's
2785 |* 		die eine Fixe Groesse haben, proportional zur Groessenaenderung der
2786 |* 		PrtArea des Frm's.
2787 |* 		Die Variablen Frm's werden auch proportional angepasst; sie werden
2788 |* 		sich schon wieder zurechtwachsen/-schrumpfen.
2789 |*	Ersterstellung		MA 11.03.92
2790 |*	Letzte Aenderung	AMA 2. Nov. 98
2791 |*
2792 |*************************************************************************/
2793 void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
2794 {
2795     // no change of lower properties for root frame or if no lower exists.
2796     if ( IsRootFrm() || !Lower() )
2797 		return;
2798 
2799     // declare and init <SwFrm* pLowerFrm> with first lower
2800     SwFrm *pLowerFrm = Lower();
2801 
2802     // declare and init const booleans <bHeightChgd> and <bWidthChg>
2803     const bool bHeightChgd = rOldSize.Height() != Prt().Height();
2804     const bool bWidthChgd  = rOldSize.Width()  != Prt().Width();
2805 
2806     // declare and init variables <bVert>, <bRev> and <fnRect>
2807     SWRECTFN( this )
2808 
2809     // This shortcut basically tries to handle only lower frames that
2810     // are affected by the size change. Otherwise much more lower frames
2811     // are invalidated.
2812     if ( !( bVert ? bHeightChgd : bWidthChgd ) &&
2813          ! Lower()->IsColumnFrm() &&
2814            ( ( IsBodyFrm() && IsInDocBody() && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) ) ||
2815                 // --> FME 2004-07-21 #i10826# Section frames without columns should not
2816                 // invalidate all lowers!
2817                IsSctFrm() ) )
2818                // <--
2819     {
2820         // Determine page frame the body frame resp. the section frame belongs to.
2821 		SwPageFrm *pPage = FindPageFrm();
2822         // Determine last lower by traveling through them using <GetNext()>.
2823         // During travel check each section frame, if it will be sized to
2824         // maximum. If Yes, invalidate size of section frame and set
2825         // corresponding flags at the page.
2826         do
2827         {
2828             if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() )
2829             {
2830                 pLowerFrm->_InvalidateSize();
2831                 pLowerFrm->InvalidatePage( pPage );
2832             }
2833             if( pLowerFrm->GetNext() )
2834                 pLowerFrm = pLowerFrm->GetNext();
2835             else
2836                 break;
2837         } while( sal_True );
2838         // If found last lower is a section frame containing no section
2839         // (section frame isn't valid and will be deleted in the future),
2840         // travel backwards.
2841         while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() &&
2842                pLowerFrm->GetPrev() )
2843             pLowerFrm = pLowerFrm->GetPrev();
2844         // If found last lower is a section frame, set <pLowerFrm> to its last
2845         // content, if the section frame is valid and is not sized to maximum.
2846         // Otherwise set <pLowerFrm> to NULL - In this case body frame only
2847         //      contains invalid section frames.
2848         if( pLowerFrm->IsSctFrm() )
2849             pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() &&
2850                    !((SwSectionFrm*)pLowerFrm)->ToMaximize( sal_False ) ?
2851                    ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL;
2852 
2853         // continue with found last lower, probably the last content of a section
2854         if ( pLowerFrm )
2855 		{
2856             // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table
2857             // frame and continue.
2858             if ( pLowerFrm->IsInTab() )
2859             {
2860                 // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to
2861                 // its table frame - check, if the table frame is also a lower
2862                 // of the body frame, in order to assure that <pLowerFrm> is not
2863                 // set to a frame, which is an *upper* of the body frame.
2864                 SwFrm* pTableFrm = pLowerFrm->FindTabFrm();
2865                 if ( IsAnLower( pTableFrm ) )
2866                 {
2867                     pLowerFrm = pTableFrm;
2868                 }
2869             }
2870             // Check, if variable size of body frame resp. section frame has grown
2871             // OD 28.10.2002 #97265# - correct check, if variable size has grown.
2872             SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height();
2873             if( nOldHeight < (Prt().*fnRect->fnGetHeight)() )
2874 			{
2875                 // If variable size of body|section frame has grown, only found
2876                 // last lower and the position of the its next have to be invalidated.
2877                 pLowerFrm->_InvalidateAll();
2878                 pLowerFrm->InvalidatePage( pPage );
2879                 if( !pLowerFrm->IsFlowFrm() ||
2880                     !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() )
2881                     pLowerFrm->InvalidateNextPos( sal_True );
2882                 if ( pLowerFrm->IsTxtFrm() )
2883                     ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2884 			}
2885 			else
2886 			{
2887                 // variable size of body|section frame has shrinked. Thus,
2888                 // invalidate all lowers not matching the new body|section size
2889                 // and the dedicated new last lower.
2890                 if( bVert )
2891                 {
2892                     SwTwips nBot = Frm().Left() + Prt().Left();
2893                     while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot )
2894                     {
2895                         pLowerFrm->_InvalidateAll();
2896                         pLowerFrm->InvalidatePage( pPage );
2897                         pLowerFrm = pLowerFrm->GetPrev();
2898                     }
2899                 }
2900                 else
2901                 {
2902                     SwTwips nBot = Frm().Top() + Prt().Bottom();
2903                     while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot )
2904                     {
2905                         pLowerFrm->_InvalidateAll();
2906                         pLowerFrm->InvalidatePage( pPage );
2907                         pLowerFrm = pLowerFrm->GetPrev();
2908                     }
2909                 }
2910                 if ( pLowerFrm )
2911 				{
2912                     pLowerFrm->_InvalidateSize();
2913                     pLowerFrm->InvalidatePage( pPage );
2914                     if ( pLowerFrm->IsTxtFrm() )
2915                         ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2916 				}
2917 			}
2918             // --> OD 2005-01-31 #i41694# - improvement by removing duplicates
2919             if ( pLowerFrm )
2920             {
2921                 if ( pLowerFrm->IsInSct() )
2922                 {
2923                     // --> OD 2005-01-31 #i41694# - follow-up of issue #i10826#:
2924                     // No invalidation of section frame, if it's the this.
2925                     SwFrm* pSectFrm = pLowerFrm->FindSctFrm();
2926                     if( pSectFrm != this && IsAnLower( pSectFrm ) )
2927                     {
2928                         pSectFrm->_InvalidateSize();
2929                         pSectFrm->InvalidatePage( pPage );
2930                     }
2931                     // <--
2932                 }
2933             }
2934             // <--
2935         }
2936 		return;
2937     } // end of { special case }
2938 
2939 
2940     // Invalidate page for content only once.
2941     bool bInvaPageForCntnt = true;
2942 
2943     // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
2944     // adjustment, if fixed/variable size has changed.
2945     bool bFixChgd, bVarChgd;
2946     if( bVert == pLowerFrm->IsNeighbourFrm() )
2947 	{
2948 		bFixChgd = bWidthChgd;
2949 		bVarChgd = bHeightChgd;
2950 	}
2951 	else
2952 	{
2953 		bFixChgd = bHeightChgd;
2954 		bVarChgd = bWidthChgd;
2955 	}
2956 
2957     // Declare const unsigned short <nFixWidth> and init it this frame types
2958     // which has fixed width in vertical respectively horizontal layout.
2959     // In vertical layout these are neighbour frames (cell and column frames),
2960     //      header frames and footer frames.
2961     // In horizontal layout these are all frames, which aren't neighbour frames.
2962     const sal_uInt16 nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
2963                                    : ~FRM_NEIGHBOUR;
2964 
2965     // Declare const unsigned short <nFixHeight> and init it this frame types
2966     // which has fixed height in vertical respectively horizontal layout.
2967     // In vertical layout these are all frames, which aren't neighbour frames,
2968     //      header frames, footer frames, body frames or foot note container frames.
2969     // In horizontal layout these are neighbour frames.
2970     const sal_uInt16 nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
2971                                    : FRM_NEIGHBOUR;
2972 
2973     // Travel through all lowers using <GetNext()>
2974     while ( pLowerFrm )
2975     {
2976         if ( pLowerFrm->IsTxtFrm() )
2977 		{
2978             // Text frames will only be invalidated - prepare invalidation
2979 			if ( bFixChgd )
2980                 static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG );
2981 			if ( bVarChgd )
2982                 static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2983 		}
2984         else
2985         {
2986             // If lower isn't a table, row, cell or section frame, adjust its
2987             // frame size.
2988             const sal_uInt16 nLowerType = pLowerFrm->GetType();
2989             if ( !(nLowerType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
2990             {
2991                 if ( bWidthChgd )
2992                 {
2993                     if( nLowerType & nFixWidth )
2994                     {
2995                         // Considering previous conditions:
2996                         // In vertical layout set width of column, header and
2997                         // footer frames to its upper width.
2998                         // In horizontal layout set width of header, footer,
2999                         // foot note container, foot note, body and no-text
3000                         // frames to its upper width.
3001                         pLowerFrm->Frm().Width( Prt().Width() );
3002                     }
3003                     else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() )
3004                     {
3005                         // Adjust frame width proportional, if lower isn't a
3006                         // foot note frame and condition <nLowerType & nFixWidth>
3007                         // isn't true.
3008                         // Considering previous conditions:
3009                         // In vertical layout these are foot note container,
3010                         // body and no-text frames.
3011                         // In horizontal layout these are column and no-text frames.
3012                         // OD 24.10.2002 #97265# - <double> calculation
3013                         // Perform <double> calculation of new width, if
3014                         // one of the coefficients is greater than 50000
3015                         SwTwips nNewWidth;
3016                         if ( (pLowerFrm->Frm().Width() > 50000) ||
3017                              (Prt().Width() > 50000) )
3018                         {
3019                             double nNewWidthTmp =
3020                                 ( double(pLowerFrm->Frm().Width())
3021                                   * double(Prt().Width()) )
3022                                 / double(rOldSize.Width());
3023                             nNewWidth = SwTwips(nNewWidthTmp);
3024                         }
3025                         else
3026                         {
3027                             nNewWidth =
3028                                 (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width();
3029                         }
3030                         pLowerFrm->Frm().Width( nNewWidth );
3031                     }
3032                 }
3033                 if ( bHeightChgd )
3034                 {
3035                     if( nLowerType & nFixHeight )
3036                     {
3037                         // Considering previous conditions:
3038                         // In vertical layout set height of foot note and
3039                         // no-text frames to its upper height.
3040                         // In horizontal layout set height of column frames
3041                         // to its upper height.
3042                         pLowerFrm->Frm().Height( Prt().Height() );
3043                     }
3044                     // OD 01.10.2002 #102211#
3045                     // add conditions <!pLowerFrm->IsHeaderFrm()> and
3046                     // <!pLowerFrm->IsFooterFrm()> in order to avoid that
3047                     // the <Grow> of header or footer are overwritten.
3048                     // NOTE: Height of header/footer frame is determined by contents.
3049                     else if ( rOldSize.Height() &&
3050                               !pLowerFrm->IsFtnFrm() &&
3051                               !pLowerFrm->IsHeaderFrm() &&
3052                               !pLowerFrm->IsFooterFrm()
3053                             )
3054                     {
3055                         // Adjust frame height proportional, if lower isn't a
3056                         // foot note, a header or a footer frame and
3057                         // condition <nLowerType & nFixHeight> isn't true.
3058                         // Considering previous conditions:
3059                         // In vertical layout these are column, foot note container,
3060                         // body and no-text frames.
3061                         // In horizontal layout these are column, foot note
3062                         // container, body and no-text frames.
3063 
3064                         // OD 29.10.2002 #97265# - special case for page lowers
3065                         // The page lowers that have to be adjusted on page height
3066                         // change are the body frame and the foot note container
3067                         // frame.
3068                         // In vertical layout the height of both is directly
3069                         // adjusted to the page height change.
3070                         // In horizontal layout the height of the body frame is
3071                         // directly adjsuted to the page height change and the
3072                         // foot note frame height isn't touched, because its
3073                         // determined by its content.
3074                         // OD 31.03.2003 #108446# - apply special case for page
3075                         // lowers - see description above - also for section columns.
3076                         if ( IsPageFrm() ||
3077                              ( IsColumnFrm() && IsInSct() )
3078                            )
3079                         {
3080                             ASSERT( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(),
3081                                     "ChgLowersProp - only for body or foot note container" );
3082                             if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() )
3083                             {
3084                                 if ( IsVertical() || pLowerFrm->IsBodyFrm() )
3085                                 {
3086                                     SwTwips nNewHeight =
3087                                             pLowerFrm->Frm().Height() +
3088                                             ( Prt().Height() - rOldSize.Height() );
3089                                     if ( nNewHeight < 0)
3090                                     {
3091                                         // OD 01.04.2003 #108446# - adjust assertion condition and text
3092                                         ASSERT( !( IsPageFrm() &&
3093                                                    (pLowerFrm->Frm().Height()>0) &&
3094                                                    (pLowerFrm->IsValid()) ),
3095                                                     "ChgLowersProg - negative height for lower.");
3096                                         nNewHeight = 0;
3097                                     }
3098                                     pLowerFrm->Frm().Height( nNewHeight );
3099                                 }
3100                             }
3101                         }
3102                         else
3103                         {
3104                             SwTwips nNewHeight;
3105                             // OD 24.10.2002 #97265# - <double> calculation
3106                             // Perform <double> calculation of new height, if
3107                             // one of the coefficients is greater than 50000
3108                             if ( (pLowerFrm->Frm().Height() > 50000) ||
3109                                  (Prt().Height() > 50000) )
3110                             {
3111                                 double nNewHeightTmp =
3112                                     ( double(pLowerFrm->Frm().Height())
3113                                       * double(Prt().Height()) )
3114                                     / double(rOldSize.Height());
3115                                 nNewHeight = SwTwips(nNewHeightTmp);
3116                             }
3117                             else
3118                             {
3119                                 nNewHeight = ( pLowerFrm->Frm().Height()
3120                                              * Prt().Height() ) / rOldSize.Height();
3121                             }
3122                             if( !pLowerFrm->GetNext() )
3123                             {
3124                                 SwTwips nSum = Prt().Height();
3125                                 SwFrm* pTmp = Lower();
3126                                 while( pTmp->GetNext() )
3127                                 {
3128                                     if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() )
3129                                         nSum -= pTmp->Frm().Height();
3130                                     pTmp = pTmp->GetNext();
3131                                 }
3132                                 if( nSum - nNewHeight == 1 &&
3133                                     nSum == pLowerFrm->Frm().Height() )
3134                                     nNewHeight = nSum;
3135                             }
3136                             pLowerFrm->Frm().Height( nNewHeight );
3137                         }
3138                     }
3139                 }
3140             }
3141         } // end of else { NOT text frame }
3142 
3143         pLowerFrm->_InvalidateAll();
3144         if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() )
3145         {
3146             pLowerFrm->InvalidatePage();
3147             bInvaPageForCntnt = false;
3148         }
3149 
3150         if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() )
3151 		{
3152 			//Wenn ein Wachstum stattgefunden hat, und die untergeordneten
3153 			//zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so
3154 			//trigger ich sie an.
3155 			if ( rOldSize.Height() < Prt().SSize().Height() ||
3156 				 rOldSize.Width() < Prt().SSize().Width() )
3157                 pLowerFrm->SetRetouche();
3158 		}
3159         pLowerFrm = pLowerFrm->GetNext();
3160 	}
3161 
3162     // Finally adjust the columns if width is set to auto
3163     // Possible optimisation: execute this code earlier in this function and
3164     // return???
3165     if ( ( (bVert && bHeightChgd) || (! bVert && bWidthChgd) ) &&
3166            Lower()->IsColumnFrm() )
3167     {
3168         // get column attribute
3169 	    const SwFmtCol* pColAttr = NULL;
3170         if ( IsPageBodyFrm() )
3171         {
3172             ASSERT( GetUpper()->IsPageFrm(), "Upper is not page frame" )
3173             pColAttr = &GetUpper()->GetFmt()->GetCol();
3174         }
3175         else
3176         {
3177             ASSERT( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" )
3178             pColAttr = &GetFmt()->GetCol();
3179 		}
3180 
3181 		if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
3182             AdjustColumns( pColAttr, sal_False );
3183 	}
3184 }
3185 
3186 /*************************************************************************
3187 |*
3188 |*	SwLayoutFrm::Format()
3189 |*
3190 |*	Beschreibung:		"Formatiert" den Frame; Frm und PrtArea.
3191 |*						Die Fixsize wird hier nicht eingestellt.
3192 |*	Ersterstellung		MA 28. Jul. 92
3193 |*	Letzte Aenderung	MA 21. Mar. 95
3194 |*
3195 |*************************************************************************/
3196 void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
3197 {
3198 	ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );
3199 
3200 	if ( bValidPrtArea && bValidSize )
3201 		return;
3202 
3203     const sal_uInt16 nLeft = (sal_uInt16)pAttrs->CalcLeft( this );
3204     const sal_uInt16 nUpper = pAttrs->CalcTop();
3205 
3206     const sal_uInt16 nRight = (sal_uInt16)((SwBorderAttrs*)pAttrs)->CalcRight( this );
3207     const sal_uInt16 nLower = pAttrs->CalcBottom();
3208     sal_Bool bVert = IsVertical() && !IsPageFrm();
3209     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
3210     SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
3211 	if ( !bValidPrtArea )
3212 	{
3213 		bValidPrtArea = sal_True;
3214         (this->*fnRect->fnSetXMargins)( nLeft, nRight );
3215         (this->*fnRect->fnSetYMargins)( nUpper, nLower );
3216 	}
3217 
3218 	if ( !bValidSize )
3219 	{
3220         if ( !HasFixSize() )
3221 		{
3222             const SwTwips nBorder = nUpper + nLower;
3223 			const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
3224             SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
3225 			do
3226 			{	bValidSize = sal_True;
3227 
3228 				//Die Groesse in der VarSize wird durch den Inhalt plus den
3229 				//Raendern bestimmt.
3230 				SwTwips nRemaining = 0;
3231 				SwFrm *pFrm = Lower();
3232 				while ( pFrm )
3233                 {   nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
3234 					if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
3235 					// Dieser TxtFrm waere gern ein bisschen groesser
3236 						nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
3237                                       - (pFrm->Prt().*fnRect->fnGetHeight)();
3238 					else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
3239 						nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
3240 					pFrm = pFrm->GetNext();
3241 				}
3242 				nRemaining += nBorder;
3243 				nRemaining = Max( nRemaining, nMinHeight );
3244                 const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)();
3245                 const long nOldLeft = (Frm().*fnRect->fnGetLeft)();
3246                 const long nOldTop = (Frm().*fnRect->fnGetTop)();
3247 				if ( nDiff )
3248 				{
3249 					if ( nDiff > 0 )
3250                         Grow( nDiff );
3251 					else
3252                         Shrink( -nDiff );
3253 					//Schnell auf dem kurzen Dienstweg die Position updaten.
3254 					MakePos();
3255 				}
3256 				//Unterkante des Uppers nicht ueberschreiten.
3257                 if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() )
3258 				{
3259                     const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
3260                     if( (this->*fnRect->fnSetLimit)( nLimit ) &&
3261                         nOldLeft == (Frm().*fnRect->fnGetLeft)() &&
3262                         nOldTop  == (Frm().*fnRect->fnGetTop)() )
3263                         bValidSize = bValidPrtArea = sal_True;
3264 				}
3265 			} while ( !bValidSize );
3266 		}
3267 		else if ( GetType() & 0x0018 )
3268 		{
3269 			do
3270 			{	if ( Frm().Height() != pAttrs->GetSize().Height() )
3271 					ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
3272 				bValidSize = sal_True;
3273 				MakePos();
3274 			} while ( !bValidSize );
3275 		}
3276 		else
3277 			bValidSize = sal_True;
3278 	}
3279 }
3280 
3281 /*************************************************************************
3282 |*
3283 |*	SwLayoutFrm::InvalidatePercentLowers()
3284 |*
3285 |*	Ersterstellung		MA 13. Jun. 96
3286 |*	Letzte Aenderung	MA 13. Jun. 96
3287 |*
3288 |*************************************************************************/
3289 static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff )
3290 {
3291 	ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" );
3292 	for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
3293 	{
3294         SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3295         if ( pAnchoredObj->ISA(SwFlyFrm) )
3296 		{
3297             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3298 			const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
3299 			if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3300             {
3301                 sal_Bool bNotify = sal_True;
3302                 // If we've a fly with more than 90% relative height...
3303                 if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrm() &&
3304                     rSz.GetHeightPercent() != 0xFF && nDiff )
3305                 {
3306                     const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchorFrm():
3307                                         pFly->GetAnchorFrm()->GetUpper();
3308                     // ... and we have already more than 90% height and we
3309                     // not allow the text to go through...
3310                     // then a notifycation could cause an endless loop, e.g.
3311                     // 100% height and no text wrap inside a cell of a table.
3312                     if( pFly->Frm().Height()*10 >
3313                         ( nDiff + pRel->Prt().Height() )*9 &&
3314                         pFly->GetFmt()->GetSurround().GetSurround() !=
3315                         SURROUND_THROUGHT )
3316                        bNotify = sal_False;
3317                 }
3318                 if( bNotify )
3319                     pFly->InvalidateSize();
3320             }
3321 		}
3322 	}
3323 }
3324 
3325 void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff )
3326 {
3327 	if ( GetDrawObjs() )
3328         ::InvaPercentFlys( this, nDiff );
3329 
3330 	SwFrm *pFrm = ContainsCntnt();
3331 	if ( pFrm )
3332 		do
3333 		{
3334 			if ( pFrm->IsInTab() && !IsTabFrm() )
3335 			{
3336 				SwFrm *pTmp = pFrm->FindTabFrm();
3337 				ASSERT( pTmp, "Where's my TabFrm?" );
3338 				if( IsAnLower( pTmp ) )
3339 					pFrm = pTmp;
3340 			}
3341 
3342 			if ( pFrm->IsTabFrm() )
3343 			{
3344 				const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
3345 				if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3346 					pFrm->InvalidatePrt();
3347 			}
3348 			else if ( pFrm->GetDrawObjs() )
3349                 ::InvaPercentFlys( pFrm, nDiff );
3350 			pFrm = pFrm->FindNextCnt();
3351 		} while ( pFrm && IsAnLower( pFrm ) ) ;
3352 }
3353 
3354 /*************************************************************************
3355 |*
3356 |*	SwLayoutFrm::CalcRel()
3357 |*
3358 |*	Ersterstellung		MA 13. Jun. 96
3359 |*	Letzte Aenderung	MA 10. Oct. 96
3360 |*
3361 |*************************************************************************/
3362 long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, sal_Bool ) const
3363 {
3364     long nRet     = rSz.GetWidth(),
3365 		 nPercent = rSz.GetWidthPercent();
3366 
3367 	if ( nPercent )
3368 	{
3369 		const SwFrm *pRel = GetUpper();
3370 		long nRel = LONG_MAX;
3371 		const ViewShell *pSh = getRootFrm()->GetCurrShell();
3372         const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
3373         if( pRel->IsPageBodyFrm() && pSh && bBrowseMode && pSh->VisArea().Width() )
3374 		{
3375 			nRel = pSh->GetBrowseWidth();
3376 			long nDiff = nRel - pRel->Prt().Width();
3377 			if ( nDiff > 0 )
3378 				nRel -= nDiff;
3379 		}
3380 		nRel = Min( nRel, pRel->Prt().Width() );
3381 		nRet = nRel * nPercent / 100;
3382 	}
3383 	return nRet;
3384 }
3385 
3386 /*************************************************************************
3387 |*  Local helpers for SwLayoutFrm::FormatWidthCols()
3388 |*************************************************************************/
3389 long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
3390 {
3391 	long nDiff = 0, nFirstDiff = 0;
3392 	SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
3393 	ASSERT( pCol, "Where's the columnframe?" );
3394 	SwFrm *pFrm = pCol->Lower();
3395 	do
3396     {
3397         if( pFrm && pFrm->IsBodyFrm() )
3398             pFrm = ((SwBodyFrm*)pFrm)->Lower();
3399         if ( pFrm && pFrm->IsTxtFrm() )
3400 		{
3401 			const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
3402 			if ( nTmp != USHRT_MAX )
3403 			{
3404 				if ( pCol == pLayFrm->Lower() )
3405 					nFirstDiff = nTmp;
3406 				else
3407 					nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp;
3408 			}
3409 		}
3410 		//Leere Spalten ueberspringen!
3411 		pCol = (SwLayoutFrm*)pCol->GetNext();
3412 		while ( pCol && 0 == (pFrm = pCol->Lower()) )
3413 			pCol = (SwLayoutFrm*)pCol->GetNext();
3414 
3415 	} while ( pFrm && pCol );
3416 
3417 	return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
3418 }
3419 
3420 sal_Bool lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
3421 {
3422 	SwFrm *pFrm = pLay->ContainsCntnt();
3423 	while ( pFrm )
3424     {
3425         if ( pFrm->IsInTab() )
3426 			pFrm = pFrm->FindTabFrm();
3427 
3428 		if ( pFrm->GetDrawObjs() )
3429 		{
3430             sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
3431 			for ( sal_uInt16 i = 0; i < nCnt; ++i )
3432 			{
3433                 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3434                 if ( pAnchoredObj->ISA(SwFlyFrm) )
3435                 {
3436                     SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3437                     if ( pFly->IsHeightClipped() &&
3438                          ( !pFly->IsFlyFreeFrm() || pFly->GetPageFrm() ) )
3439                         return sal_True;
3440                 }
3441 			}
3442 		}
3443 		pFrm = pFrm->FindNextCnt();
3444 	}
3445 	return sal_False;
3446 }
3447 
3448 /*************************************************************************
3449 |*  SwLayoutFrm::FormatWidthCols()
3450 |*************************************************************************/
3451 void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
3452                                    const SwTwips nBorder, const SwTwips nMinHeight )
3453 {
3454 	//Wenn Spalten im Spiel sind, so wird die Groesse an der
3455 	//letzten Spalte ausgerichtet.
3456 	//1. Inhalt formatieren.
3457 	//2. Hoehe der letzten Spalte ermitteln, wenn diese zu
3458 	//	 zu gross ist muss der Fly wachsen.
3459 	//	 Der Betrag um den der Fly waechst ist aber nicht etwa
3460 	//	 der Betrag des Ueberhangs, denn wir muessen davon
3461 	//	 ausgehen, dass etwas Masse zurueckfliesst und so
3462 	//	 zusaetzlicher Platz geschaffen wird.
3463 	//	 Im Ersten Ansatz ist der Betrag um den gewachsen wird
3464 	//	 der Ueberhang geteilt durch die Spaltenanzahl oder
3465 	//	 der Ueberhang selbst wenn er kleiner als die Spalten-
3466 	//	 anzahl ist.
3467 	//3. Weiter mit 1. bis zur Stabilitaet.
3468 
3469 	const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
3470 	const sal_uInt16 nNumCols = rCol.GetNumCols();
3471 
3472 	sal_Bool bEnd = sal_False;
3473 	sal_Bool bBackLock = sal_False;
3474 	ViewShell *pSh = getRootFrm()->GetCurrShell();
3475 	SwViewImp *pImp = pSh ? pSh->Imp() : 0;
3476 	{
3477 		// Zugrunde liegender Algorithmus
3478 		// Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden.
3479 		// nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als
3480 		// Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer
3481 		// Spalte herausragt.
3482 		// nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt,
3483 		// bei denen der Inhalt gepasst hat.
3484 		// Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den
3485 		// die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch
3486 		// Inhalt heraushaengt.
3487 		// Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum
3488 		// ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber
3489 		// ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern
3490 		// noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um
3491 		// nMinDiff, aber nicht unter das nMinimum.
3492 		// Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf
3493 		// weniger als ein MinDiff dem Maximum angenaehert hat oder das von der
3494 		// Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus-
3495 		// haengt.
3496 
3497 		// Kritik an der Implementation
3498 		// 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren
3499 		// Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust
3500 		// gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum
3501 		// drin, die wahrscheinlich niemals zuschlagen koennen.
3502 		// 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum,
3503 		// das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und
3504 		// als Mindestwert fuer das Schrumpfen nicht unbedingt optimal.
3505 
3506 		long nMinimum = nMinHeight;
3507 		long nMaximum;
3508 		sal_Bool bNoBalance = sal_False;
3509         SWRECTFN( this )
3510 		if( IsSctFrm() )
3511 		{
3512             nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder +
3513                        (Frm().*fnRect->fnBottomDist)(
3514                                         (GetUpper()->*fnRect->fnGetPrtBottom)() );
3515             nMaximum += GetUpper()->Grow( LONG_MAX, sal_True );
3516 			if( nMaximum < nMinimum )
3517 			{
3518 				if( nMaximum < 0 )
3519 					nMinimum = nMaximum = 0;
3520 				else
3521 					nMinimum = nMaximum;
3522 			}
3523 			if( nMaximum > BROWSE_HEIGHT )
3524 				nMaximum = BROWSE_HEIGHT;
3525 
3526 			bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()->
3527 						 GetBalancedColumns().GetValue();
3528 			SwFrm* pAny = ContainsAny();
3529 			if( bNoBalance ||
3530                 ( !(Frm().*fnRect->fnGetHeight)() && pAny ) )
3531 			{
3532                 long nTop = (this->*fnRect->fnGetTopMargin)();
3533                 // --> OD 2004-11-01 #i23129# - correction: enlarge section
3534                 // to the calculated maximum height.
3535                 (Frm().*fnRect->fnAddBottom)( nMaximum -
3536                                               (Frm().*fnRect->fnGetHeight)() );
3537                 // <--
3538                 if( nTop > nMaximum )
3539                     nTop = nMaximum;
3540                 (this->*fnRect->fnSetYMargins)( nTop, 0 );
3541 			}
3542 			if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() )
3543 			{
3544 				SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont();
3545 				if( pFtnCont )
3546 				{
3547 					SwFrm* pFtnAny = pFtnCont->ContainsAny();
3548 					if( pFtnAny && pFtnAny->IsValid() )
3549 					{
3550 						bBackLock = sal_True;
3551 						((SwSectionFrm*)this)->SetFtnLock( sal_True );
3552 					}
3553 				}
3554 			}
3555         }
3556 		else
3557 			nMaximum = LONG_MAX;
3558 
3559         // --> OD 2004-08-25 #i3317# - reset temporarly consideration
3560         // of wrapping style influence
3561         SwPageFrm* pPageFrm = FindPageFrm();
3562         SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
3563         if ( pObjs )
3564         {
3565             sal_uInt32 i = 0;
3566             for ( i = 0; i < pObjs->Count(); ++i )
3567             {
3568                 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
3569 
3570                 if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3571                 {
3572                     pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3573                 }
3574             }
3575         }
3576         // <--
3577         do
3578 		{
3579 			//Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen.
3580 			if ( pImp )
3581 				pImp->CheckWaitCrsr();
3582 
3583 			bValidSize = sal_True;
3584 			//Erstmal die Spalten formatieren, das entlastet den
3585 			//Stack ein wenig.
3586 			//Bei der Gelegenheit stellen wir auch gleich mal die
3587 			//Breiten und Hoehen der Spalten ein (so sie denn falsch sind).
3588 			SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
3589 
3590             // --> FME 2004-07-19 #i27399#
3591             // Simply setting the column width based on the values returned by
3592             // CalcColWidth does not work for automatic column width.
3593             AdjustColumns( &rCol, sal_False );
3594             // <--
3595 
3596             for ( sal_uInt16 i = 0; i < nNumCols; ++i )
3597 			{
3598                 pCol->Calc();
3599 				// ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will
3600 				pCol->Lower()->Calc();
3601 				if( pCol->Lower()->GetNext() )
3602 					pCol->Lower()->GetNext()->Calc();  // SwFtnCont
3603 				pCol = (SwLayoutFrm*)pCol->GetNext();
3604             }
3605 
3606             ::CalcCntnt( this );
3607 
3608 			pCol = (SwLayoutFrm*)Lower();
3609 			ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?");
3610 			// bMinDiff wird gesetzt, wenn es keine leere Spalte gibt
3611 			sal_Bool bMinDiff = sal_True;
3612             // OD 28.03.2003 #108446# - check for all column content and all columns
3613             while ( bMinDiff && pCol )
3614             {
3615                 bMinDiff = 0 != pCol->ContainsCntnt();
3616                 pCol = (SwLayoutFrm*)pCol->GetNext();
3617             }
3618 			pCol = (SwLayoutFrm*)Lower();
3619             // OD 28.03.2003 #108446# - initialize local variable
3620             SwFrm *pLow = NULL;
3621 			SwTwips nDiff = 0;
3622 			SwTwips nMaxFree = 0;
3623 			SwTwips nAllFree = LONG_MAX;
3624 			// bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt
3625 			sal_Bool bFoundLower = sal_False;
3626 			while( pCol )
3627 			{
3628 				SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
3629                 SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() -
3630                                        (pLay->Prt().*fnRect->fnGetHeight)();
3631 				if( pLay->Lower() )
3632 				{
3633 					bFoundLower = sal_True;
3634 					nInnerHeight += pLay->InnerHeight();
3635 				}
3636 				else if( nInnerHeight < 0 )
3637 					nInnerHeight = 0;
3638 
3639 				if( pLay->GetNext() )
3640 				{
3641 					bFoundLower = sal_True;
3642 					pLay = (SwLayoutFrm*)pLay->GetNext();
3643 					ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" );
3644 					nInnerHeight += pLay->InnerHeight();
3645                     nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() -
3646                                     (pLay->Prt().*fnRect->fnGetHeight)();
3647 				}
3648                 nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)();
3649 				if( nInnerHeight > nDiff )
3650 				{
3651 					nDiff = nInnerHeight;
3652 					nAllFree = 0;
3653 				}
3654 				else
3655 				{
3656 					if( nMaxFree < -nInnerHeight )
3657 						nMaxFree = -nInnerHeight;
3658 					if( nAllFree > -nInnerHeight )
3659 						nAllFree = -nInnerHeight;
3660 				}
3661 				pCol = (SwLayoutFrm*)pCol->GetNext();
3662 			}
3663 
3664 			if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
3665 			{
3666 				SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
3667 				// Hier wird entschieden, ob wir wachsen muessen, naemlich wenn
3668 				// ein Spalteninhalt (nDiff) oder ein Fly herausragt.
3669 				// Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem
3670 				// Besitz eines nichtleeren Follows die Groesse festgelegt ist.
3671 				if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
3672 					 ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
3673 				{
3674                     long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3675 					// Das Minimum darf nicht kleiner sein als unsere PrtHeight,
3676 					// solange noch etwas herausragt.
3677                     if( nMinimum < nPrtHeight )
3678                         nMinimum = nPrtHeight;
3679 					// Es muss sichergestellt sein, dass das Maximum nicht kleiner
3680 					// als die PrtHeight ist, wenn noch etwas herausragt
3681                     if( nMaximum < nPrtHeight )
3682                         nMaximum = nPrtHeight;  // Robust, aber kann das ueberhaupt eintreten?
3683 					if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff
3684 						nDiff = nMinDiff;
3685 					// Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die
3686 					// Spalten verteilt
3687 					if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
3688 						nDiff /= nNumCols;
3689 
3690 					if ( bMinDiff )
3691 					{   // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff
3692 						// wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe
3693 						// sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so,
3694 						// dass die PrtHeight hinterher genau nMinDiff ist.
3695                         long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
3696                         if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff )
3697 							nDiff = Max( nDiff, nMinDiff );
3698 						else if( nDiff < nMinDiff )
3699                             nDiff = nMinDiff - nPrtHeight + 1;
3700 					}
3701 					// nMaximum ist eine Groesse, in der der Inhalt gepasst hat,
3702 					// oder der von der Umgebung vorgegebene Wert, deshalb
3703 					// brauchen wir nicht ueber diesen Wrt hinauswachsen.
3704                     if( nDiff + nPrtHeight > nMaximum )
3705                         nDiff = nMaximum - nPrtHeight;
3706 				}
3707 				else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum?
3708 				{
3709                     long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3710                     if ( nMaximum < nPrtHeight )
3711                         nDiff = nMaximum - nPrtHeight; // wir sind ueber eine funktionierende
3712 						// Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck,
3713 						// aber kann das ueberhaupt eintreten?
3714 					else
3715 					{   // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt.
3716                         nMaximum = nPrtHeight;
3717 						// Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir
3718 						// nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig
3719 						// Luft herauslassen.
3720                         if ( !bNoBalance &&
3721                              // --> OD 2004-11-04 #i23129# - <nMinDiff> can be
3722                              // big, because of an object at the beginning of
3723                              // a column. Thus, decrease optimization here.
3724                              //nMaxFree >= nMinDiff &&
3725                              nMaxFree > 0 &&
3726                              // <--
3727                              ( !nAllFree ||
3728                                nMinimum < nPrtHeight - nMinDiff ) )
3729 						{
3730 							nMaxFree /= nNumCols; // auf die Spalten verteilen
3731 							nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff
3732                             if( nPrtHeight + nDiff <= nMinimum ) // Unter das Minimum?
3733 								nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte
3734 						}
3735 						else if( nAllFree )
3736 						{
3737 							nDiff = -nAllFree;
3738                             if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
3739 								nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3740 						}
3741 					}
3742 				}
3743 				if( nDiff ) // jetzt wird geschrumpft oder gewachsen..
3744 				{
3745 					Size aOldSz( Prt().SSize() );
3746                     long nTop = (this->*fnRect->fnGetTopMargin)();
3747                     nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder -
3748                             (Frm().*fnRect->fnGetHeight)();
3749                     (Frm().*fnRect->fnAddBottom)( nDiff );
3750                     // --> OD 2006-08-16 #i68520#
3751                     if ( dynamic_cast<SwFlyFrm*>(this) )
3752                     {
3753                         dynamic_cast<SwFlyFrm*>(this)->InvalidateObjRectWithSpaces();
3754                     }
3755                     // <--
3756                     (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop );
3757 					ChgLowersProp( aOldSz );
3758                     NotifyLowerObjs();
3759 
3760                     // --> OD 2004-08-25 #i3317# - reset temporarly consideration
3761                     // of wrapping style influence
3762                     SwPageFrm* pTmpPageFrm = FindPageFrm();
3763                     SwSortedObjs* pTmpObjs = pTmpPageFrm ? pTmpPageFrm->GetSortedObjs() : 0L;
3764                     if ( pTmpObjs )
3765                     {
3766                         sal_uInt32 i = 0;
3767                         for ( i = 0; i < pTmpObjs->Count(); ++i )
3768                         {
3769                             SwAnchoredObject* pAnchoredObj = (*pTmpObjs)[i];
3770 
3771                             if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3772                             {
3773                                 pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3774                             }
3775                         }
3776                     }
3777                     // <--
3778 					//Es muss geeignet invalidiert werden, damit
3779 					//sich die Frms huebsch ausbalancieren
3780 					//- Der jeweils erste ab der zweiten Spalte bekommt
3781 					//	ein InvalidatePos();
3782 					pCol = (SwLayoutFrm*)Lower()->GetNext();
3783 					while ( pCol )
3784 					{
3785 						pLow = pCol->Lower();
3786 						if ( pLow )
3787 							pLow->_InvalidatePos();
3788 						pCol = (SwLayoutFrm*)pCol->GetNext();
3789 					}
3790 					if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
3791 					{
3792 						// Wenn wir einen Follow erzeugt haben, muessen wir
3793 						// seinem Inhalt die Chance geben, im CalcCntnt
3794 						// zurueckzufliessen
3795 						SwCntntFrm* pTmpCntnt =
3796 							((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
3797 						if( pTmpCntnt )
3798 							pTmpCntnt->_InvalidatePos();
3799 					}
3800 				}
3801 				else
3802 					bEnd = sal_True;
3803 			}
3804 			else
3805 				bEnd = sal_True;
3806 
3807 		} while ( !bEnd || !bValidSize );
3808 	}
3809     // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
3810     // 2nd parameter to <true>.
3811     ::CalcCntnt( this, true );
3812 	if( IsSctFrm() )
3813 	{
3814         // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
3815         ::CalcCntnt( this, true );
3816 		if( bBackLock )
3817 			((SwSectionFrm*)this)->SetFtnLock( sal_False );
3818 	}
3819 }
3820 
3821 
3822 /*************************************************************************
3823 |*
3824 |*	SwRootFrm::InvalidateAllCntnt()
3825 |*
3826 |*	Ersterstellung		MA 13. Feb. 98
3827 |*	Letzte Aenderung	MA 12. Aug. 00
3828 |*
3829 |*************************************************************************/
3830 
3831 SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, sal_uInt8 nInv )
3832 {
3833 	SwSectionFrm* pSect = pCnt->FindSctFrm();
3834 	// Wenn unser CntntFrm in einer Tabelle oder Fussnote steht, sind nur
3835 	// Bereiche gemeint, die ebenfalls innerhalb liegen.
3836 	// Ausnahme: Wenn direkt eine Tabelle uebergeben wird.
3837 	if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
3838 		( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
3839 		return NULL;
3840 	if( nInv & INV_SIZE )
3841 		pSect->_InvalidateSize();
3842 	if( nInv & INV_POS )
3843 		pSect->_InvalidatePos();
3844 	if( nInv & INV_PRTAREA )
3845 		pSect->_InvalidatePrt();
3846 	SwFlowFrm *pFoll = pSect->GetFollow();
3847 	// Temporary separation from follow
3848 	pSect->SetFollow( NULL );
3849 	SwCntntFrm* pRet = pSect->FindLastCntnt();
3850 	pSect->SetFollow( pFoll );
3851 	return pRet;
3852 }
3853 
3854 SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, sal_uInt8 nInv )
3855 {
3856 	if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
3857 		lcl_InvalidateSection( pTable, nInv );
3858 	if( nInv & INV_SIZE )
3859 		pTable->_InvalidateSize();
3860 	if( nInv & INV_POS )
3861 		pTable->_InvalidatePos();
3862 	if( nInv & INV_PRTAREA )
3863 		pTable->_InvalidatePrt();
3864 	return pTable->FindLastCntnt();
3865 }
3866 
3867 void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv );
3868 
3869 void lcl_InvalidateCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3870 {
3871 	SwCntntFrm *pLastTabCnt = NULL;
3872 	SwCntntFrm *pLastSctCnt = NULL;
3873 	while ( pCnt )
3874 	{
3875 		if( nInv & INV_SECTION )
3876 		{
3877 			if( pCnt->IsInSct() )
3878 			{
3879 				// Siehe oben bei Tabellen
3880 				if( !pLastSctCnt )
3881 					pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
3882 				if( pLastSctCnt == pCnt )
3883 					pLastSctCnt = NULL;
3884 			}
3885 #ifdef DBG_UTIL
3886 			else
3887 				ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" );
3888 #endif
3889 		}
3890 		if( nInv & INV_TABLE )
3891 		{
3892 			if( pCnt->IsInTab() )
3893 			{
3894 				// Um nicht fuer jeden CntntFrm einer Tabelle das FindTabFrm() zu rufen
3895 				// und wieder die gleiche Tabelle zu invalidieren, merken wir uns den letzten
3896 				// CntntFrm der Tabelle und reagieren erst wieder auf IsInTab(), wenn wir
3897 				// an diesem vorbei sind.
3898 				// Beim Eintritt in die Tabelle wird der LastSctCnt auf Null gesetzt,
3899 				// damit Bereiche im Innern der Tabelle richtig invalidiert werden.
3900 				// Sollte die Tabelle selbst in einem Bereich stehen, so wird an
3901 				// diesem die Invalidierung bis zu dreimal durchgefuehrt, das ist vertretbar.
3902 				if( !pLastTabCnt )
3903 				{
3904 					pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
3905 					pLastSctCnt = NULL;
3906 				}
3907 				if( pLastTabCnt == pCnt )
3908 				{
3909 					pLastTabCnt = NULL;
3910 					pLastSctCnt = NULL;
3911 				}
3912 			}
3913 #ifdef DBG_UTIL
3914 			else
3915 				ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" );
3916 #endif
3917 		}
3918 
3919 		if( nInv & INV_SIZE )
3920 			pCnt->Prepare( PREP_CLEAR, 0, sal_False );
3921 		if( nInv & INV_POS )
3922 			pCnt->_InvalidatePos();
3923 		if( nInv & INV_PRTAREA )
3924 			pCnt->_InvalidatePrt();
3925 		if ( nInv & INV_LINENUM )
3926 			pCnt->InvalidateLineNum();
3927 		if ( pCnt->GetDrawObjs() )
3928 			lcl_InvalidateAllCntnt( pCnt, nInv );
3929 		pCnt = pCnt->GetNextCntntFrm();
3930 	}
3931 }
3932 
3933 void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3934 {
3935     SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
3936 	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3937 	{
3938         SwAnchoredObject* pAnchoredObj = rObjs[i];
3939         if ( pAnchoredObj->ISA(SwFlyFrm) )
3940 		{
3941             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3942 			if ( pFly->IsFlyInCntFrm() )
3943             {
3944 				::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3945                 if( nInv & INV_DIRECTION )
3946                     pFly->CheckDirChange();
3947             }
3948 		}
3949 	}
3950 }
3951 
3952 void SwRootFrm::InvalidateAllCntnt( sal_uInt8 nInv )
3953 {
3954 	// Erst werden alle Seitengebundenen FlyFrms abgearbeitet.
3955 	SwPageFrm *pPage = (SwPageFrm*)Lower();
3956 	while( pPage )
3957 	{
3958 		pPage->InvalidateFlyLayout();
3959 		pPage->InvalidateFlyCntnt();
3960 		pPage->InvalidateFlyInCnt();
3961 		pPage->InvalidateLayout();
3962 		pPage->InvalidateCntnt();
3963 		pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet
3964 
3965 		if ( pPage->GetSortedObjs() )
3966 		{
3967             const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3968 			for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3969 			{
3970                 SwAnchoredObject* pAnchoredObj = rObjs[i];
3971                 if ( pAnchoredObj->ISA(SwFlyFrm) )
3972                 {
3973                     SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3974                     ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3975                     if ( nInv & INV_DIRECTION )
3976                         pFly->CheckDirChange();
3977                 }
3978 			}
3979 		}
3980         if( nInv & INV_DIRECTION )
3981             pPage->CheckDirChange();
3982 		pPage = (SwPageFrm*)(pPage->GetNext());
3983 	}
3984 
3985 	//Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys.
3986 	::lcl_InvalidateCntnt( ContainsCntnt(), nInv );
3987 
3988 	if( nInv & INV_PRTAREA )
3989 	{
3990 		ViewShell *pSh  = getRootFrm()->GetCurrShell();
3991 		if( pSh )
3992 			pSh->InvalidateWindows( Frm() );
3993 	}
3994 }
3995 
3996 /** method to invalidate/re-calculate the position of all floating
3997     screen objects (Writer fly frames and drawing objects), which are
3998     anchored to paragraph or to character.
3999 
4000     OD 2004-03-16 #i11860#
4001 
4002     @author OD
4003 */
4004 void SwRootFrm::InvalidateAllObjPos()
4005 {
4006     const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>(Lower());
4007     while( pPageFrm )
4008     {
4009         pPageFrm->InvalidateFlyLayout();
4010 
4011         if ( pPageFrm->GetSortedObjs() )
4012         {
4013             const SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
4014             for ( sal_uInt8 i = 0; i < rObjs.Count(); ++i )
4015             {
4016                 SwAnchoredObject* pAnchoredObj = rObjs[i];
4017                 const SwFmtAnchor& rAnch = pAnchoredObj->GetFrmFmt().GetAnchor();
4018                 if ((rAnch.GetAnchorId() != FLY_AT_PARA) &&
4019                     (rAnch.GetAnchorId() != FLY_AT_CHAR))
4020                 {
4021                     // only to paragraph and to character anchored objects are considered.
4022                     continue;
4023                 }
4024                 // --> OD 2004-07-07 #i28701# - special invalidation for anchored
4025                 // objects, whose wrapping style influence has to be considered.
4026                 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
4027                     pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
4028                 else
4029                     pAnchoredObj->InvalidateObjPos();
4030                 // <--
4031             }
4032         }
4033 
4034         pPageFrm = static_cast<const SwPageFrm*>(pPageFrm->GetNext());
4035     }
4036 }
4037 
4038 
4039