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