xref: /trunk/main/sw/source/core/layout/wsfrm.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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