xref: /aoo42x/main/sw/source/core/layout/sectfrm.cxx (revision 713b4dcd)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <svl/smplhint.hxx>
32 #include <svl/itemiter.hxx>
33 #include <hints.hxx>
34 #include <txtftn.hxx>
35 #include <fmtftn.hxx>
36 #include <fmtclbl.hxx>
37 #include "sectfrm.hxx"
38 #include "section.hxx"		// SwSection
39 #include "frmtool.hxx"		// StackHack
40 #include "doc.hxx"			// SwDoc
41 #include "cntfrm.hxx"		// SwCntntFrm
42 #include "rootfrm.hxx"		// SwRootFrm
43 #include "pagefrm.hxx"		// SwPageFrm
44 #include "fmtpdsc.hxx"		// SwFmtPageDesc
45 #include "fmtcntnt.hxx"		// SwFmtCntnt
46 #include "ndindex.hxx"		// SwNodeIndex
47 #include "ftnidx.hxx"
48 #include "txtfrm.hxx"		// SwTxtFrm
49 #include "fmtclds.hxx"		// SwFmtCol
50 #include "colfrm.hxx"		// SwColumnFrm
51 #include "tabfrm.hxx"		// SwTabFrm
52 #include "flyfrm.hxx"		// SwFlyFrm
53 #include "ftnfrm.hxx"		// SwFtnFrm
54 #include "layouter.hxx"		// SwLayouter
55 #include "dbg_lay.hxx"
56 #include "viewsh.hxx"
57 #include "viewopt.hxx"
58 #include "viewimp.hxx"
59 #include <editeng/ulspitem.hxx>
60 #include <editeng/lrspitem.hxx>
61 #include <editeng/brshitem.hxx>
62 #include <fmtftntx.hxx>
63 // OD 2004-05-24 #i28701#
64 #include <dflyobj.hxx>
65 #include <flyfrms.hxx>
66 #include <sortedobjs.hxx>
67 
68 SV_IMPL_PTRARR_SORT( SwDestroyList, SwSectionFrmPtr )
69 
70 /*************************************************************************
71 |*
72 |*	SwSectionFrm::SwSectionFrm(), ~SwSectionFrm()
73 |*
74 |*	Ersterstellung		AMA 26. Nov. 97
75 |*	Letzte Aenderung	AMA 26. Nov. 97
76 |*
77 |*************************************************************************/
78 SwSectionFrm::SwSectionFrm( SwSection &rSect, SwFrm* pSib ) :
79 	SwLayoutFrm( rSect.GetFmt(), pSib ),
80 	SwFlowFrm( (SwFrm&)*this ),
81 	pSection( &rSect )
82 {
83     nType = FRMC_SECTION;
84 
85 	CalcFtnAtEndFlag();
86 	CalcEndAtEndFlag();
87 }
88 
89 SwSectionFrm::SwSectionFrm( SwSectionFrm &rSect, sal_Bool bMaster ) :
90 	SwLayoutFrm( rSect.GetFmt(), rSect.getRootFrm() ),
91 	SwFlowFrm( (SwFrm&)*this ),
92 	pSection( rSect.GetSection() )
93 {
94 	bFtnAtEnd = rSect.IsFtnAtEnd();
95 	bEndnAtEnd = rSect.IsEndnAtEnd();
96 	bLockJoin = sal_False;
97     nType = FRMC_SECTION;
98 
99 	PROTOCOL( this, PROT_SECTION, bMaster ? ACT_CREATE_MASTER : ACT_CREATE_FOLLOW, &rSect )
100 
101 	if( bMaster )
102 	{
103 		if( rSect.IsFollow() )
104 		{
105             SwSectionFrm* pMaster = rSect.FindMaster();
106 			pMaster->SetFollow( this );
107 			bIsFollow = sal_True;
108 		}
109 		else
110 			rSect.bIsFollow = sal_True;
111 		SetFollow( &rSect );
112 	}
113 	else
114 	{
115 		bIsFollow = sal_True;
116 		SetFollow( rSect.GetFollow() );
117 		rSect.SetFollow( this );
118 		if( !GetFollow() )
119 			rSect.SimpleFormat();
120 		if( !rSect.IsColLocked() )
121 			rSect.InvalidateSize();
122 	}
123 }
124 
125 // NOTE: call <SwSectionFrm::Init()> directly after creation of a new section
126 //       frame and its insert in the layout.
127 void SwSectionFrm::Init()
128 {
129     ASSERT( GetUpper(), "SwSectionFrm::Init before insertion?!" );
130     SWRECTFN( this )
131     long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
132     (Frm().*fnRect->fnSetWidth)( nWidth );
133     (Frm().*fnRect->fnSetHeight)( 0 );
134 
135     // #109700# LRSpace for sections
136     const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
137     (Prt().*fnRect->fnSetLeft)( rLRSpace.GetLeft() );
138     (Prt().*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() -
139                                  rLRSpace.GetRight() );
140     (Prt().*fnRect->fnSetHeight)( 0 );
141 
142     const SwFmtCol &rCol = GetFmt()->GetCol();
143     if( ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !IsInFtn() )
144 	{
145         const SwFmtCol *pOld = Lower() ? &rCol : new SwFmtCol;
146         ChgColumns( *pOld, rCol, IsAnyNoteAtEnd() );
147         if( pOld != &rCol )
148             delete pOld;
149 	}
150 }
151 
152 SwSectionFrm::~SwSectionFrm()
153 {
154 	if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
155 	{
156 		SwRootFrm *pRootFrm = getRootFrm();
157 		if( pRootFrm )
158 			pRootFrm->RemoveFromList( this );	//swmod 071108//swmod 071225
159 		if( IsFollow() )
160 		{
161             SwSectionFrm *pMaster = FindMaster();
162 			if( pMaster )
163 			{
164 				PROTOCOL( this, PROT_SECTION, ACT_DEL_FOLLOW, pMaster )
165 				pMaster->SetFollow( GetFollow() );
166 				// Ein Master greift sich immer den Platz bis zur Unterkante seines
167 				// Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder
168 				// freigeben, deshalb wird die Size des Masters invalidiert.
169 				if( !GetFollow() )
170 					pMaster->InvalidateSize();
171 			}
172 		}
173 		else if( HasFollow() )
174 		{
175 			PROTOCOL( this, PROT_SECTION, ACT_DEL_MASTER, GetFollow() )
176 			GetFollow()->bIsFollow = sal_False;
177 		}
178 	}
179 }
180 
181 
182 /*************************************************************************
183 |*
184 |*	SwSectionFrm::DelEmpty()
185 |*
186 |*	Ersterstellung		AMA 17. Dec. 97
187 |*	Letzte Aenderung	AMA 17. Dec. 97
188 |*
189 |*************************************************************************/
190 void SwSectionFrm::DelEmpty( sal_Bool bRemove )
191 {
192 	if( IsColLocked() )
193 	{
194 		ASSERT( !bRemove, "Don't delete locked SectionFrms" );
195 		return;
196 	}
197 	SwFrm* pUp = GetUpper();
198 	if( pUp )
199     {
200         // --> OD 2005-12-01 #i27138#
201         // notify accessibility paragraphs objects about changed
202         // CONTENT_FLOWS_FROM/_TO relation.
203         // Relation CONTENT_FLOWS_FROM for current next paragraph will change
204         // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
205         {
206             ViewShell* pViewShell( getRootFrm()->GetCurrShell() );
207             if ( pViewShell && pViewShell->GetLayout() &&
208                  pViewShell->GetLayout()->IsAnyShellAccessible() )
209             {
210                 pViewShell->InvalidateAccessibleParaFlowRelation(
211                                 dynamic_cast<SwTxtFrm*>(FindNextCnt( true )),
212                                 dynamic_cast<SwTxtFrm*>(FindPrevCnt( true )) );
213             }
214         }
215         // <--
216         _Cut( bRemove );
217     }
218 	if( IsFollow() )
219 	{
220         SwSectionFrm *pMaster = FindMaster();
221 		pMaster->SetFollow( GetFollow() );
222 		// Ein Master greift sich immer den Platz bis zur Unterkante seines
223 		// Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder
224 		// freigeben, deshalb wird die Size des Masters invalidiert.
225 		if( !GetFollow() && !pMaster->IsColLocked() )
226 			pMaster->InvalidateSize();
227 		bIsFollow = sal_False;
228 	}
229 	else if( HasFollow() )
230 		GetFollow()->bIsFollow = sal_False;
231 	pFollow = NULL;
232 	if( pUp )
233 	{
234 		Frm().Height( 0 );
235 		// Wenn wir sowieso sofort zerstoert werden, brauchen/duerfen wir
236 		// uns gar nicht erst in die Liste eintragen
237 		if( bRemove )
238 		{   // Wenn wir bereits halbtot waren vor diesem DelEmpty, so
239 			// stehen wir vermutlich auch in der Liste und muessen uns
240 			// dort austragen
241 			if( !pSection && getRootFrm() )
242 				getRootFrm()->RemoveFromList( this );
243 		}
244 		else if( getRootFrm() )
245 			getRootFrm()->InsertEmptySct( this );	//swmod 071108//swmod 071225
246 		pSection = NULL; // damit ist allerdings eine Reanimierung quasi ausgeschlossen
247 	}
248 }
249 
250 /*************************************************************************
251 |*
252 |*	SwSectionFrm::Cut()
253 |*
254 |*	Ersterstellung		AMA 02. Dec. 97
255 |*	Letzte Aenderung	AMA 02. Dec. 97
256 |*
257 |*************************************************************************/
258 void SwSectionFrm::Cut()
259 {
260 	_Cut( sal_True );
261 }
262 
263 void SwSectionFrm::_Cut( sal_Bool bRemove )
264 {
265 	ASSERT( GetUpper(), "Cut ohne Upper()." );
266 
267 	PROTOCOL( this, PROT_CUT, 0, GetUpper() )
268 
269 	SwPageFrm *pPage = FindPageFrm();
270 	InvalidatePage( pPage );
271 	SwFrm *pFrm = GetNext();
272 	SwFrm* pPrepFrm = NULL;
273 	while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
274 		pFrm = pFrm->GetNext();
275 	if( pFrm )
276 	{	//Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
277 		//berechnet der ist jetzt wo er der erste wird obsolete
278 		pFrm->_InvalidatePrt();
279 		pFrm->_InvalidatePos();
280 		if( pFrm->IsSctFrm() )
281 			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
282 		if ( pFrm && pFrm->IsCntntFrm() )
283 		{
284 			pFrm->InvalidatePage( pPage );
285 			if( IsInFtn() && !GetIndPrev() )
286 				pPrepFrm = pFrm;
287 		}
288 	}
289 	else
290 	{
291 		InvalidateNextPos();
292 		//Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
293 		if ( 0 != (pFrm = GetPrev()) )
294 		{	pFrm->SetRetouche();
295 			pFrm->Prepare( PREP_WIDOWS_ORPHANS );
296 			if ( pFrm->IsCntntFrm() )
297 				pFrm->InvalidatePage( pPage );
298 		}
299 		//Wenn ich der einzige FlowFrm in meinem Upper bin (war), so muss
300 		//er die Retouche uebernehmen.
301 		//Ausserdem kann eine Leerseite entstanden sein.
302 		else
303 		{	SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
304 			pRoot->SetSuperfluous();
305 			GetUpper()->SetCompletePaint();
306 		}
307 	}
308 	//Erst removen, dann Upper Shrinken.
309 	SwLayoutFrm *pUp = GetUpper();
310 	if( bRemove )
311 	{
312 		Remove();
313 		if( pUp && !pUp->Lower() && pUp->IsFtnFrm() && !pUp->IsColLocked() &&
314 			pUp->GetUpper() )
315 		{
316 			pUp->Cut();
317 			delete pUp;
318 			pUp = NULL;
319 		}
320 	}
321 	if( pPrepFrm )
322 		pPrepFrm->Prepare( PREP_FTN );
323 	if ( pUp )
324 	{
325         SWRECTFN( this );
326         SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
327         if( nFrmHeight > 0 )
328 		{
329 			if( !bRemove )
330 			{
331                 (Frm().*fnRect->fnSetHeight)( 0 );
332                 (Prt().*fnRect->fnSetHeight)( 0 );
333 			}
334             pUp->Shrink( nFrmHeight );
335 		}
336 	}
337 }
338 
339 /*************************************************************************
340 |*
341 |*	SwSectionFrm::Paste()
342 |*
343 |*	Ersterstellung		AMA 04. Dec. 97
344 |*	Letzte Aenderung	AMA 04. Dec. 97
345 |*
346 |*************************************************************************/
347 
348 void SwSectionFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
349 {
350 	ASSERT( pParent, "Kein Parent fuer Paste." );
351 	ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
352 	ASSERT( pParent != this, "Bin selbst der Parent." );
353 	ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
354 	ASSERT( !GetPrev() && !GetUpper(),
355 			"Bin noch irgendwo angemeldet." );
356 
357 	PROTOCOL( this, PROT_PASTE, 0, GetUpper() )
358 
359 	//In den Baum einhaengen.
360 	SwSectionFrm* pSect = pParent->FindSctFrm();
361     // --> OD 2008-06-23 #156927#
362     // Assure that parent is not inside a table frame, which is inside the found section frame.
363     if ( pSect )
364     {
365         SwTabFrm* pTableFrm = pParent->FindTabFrm();
366         if ( pTableFrm &&
367              pSect->IsAnLower( pTableFrm ) )
368         {
369             pSect = 0;
370         }
371     }
372     // <--
373 
374     SWRECTFN( pParent )
375 	if( pSect && HasToBreak( pSect ) )
376 	{
377 		if( pParent->IsColBodyFrm() ) // handelt es sich um einen spaltigen Bereich
378 		{
379 			// Falls wir zufaellig am Ende einer Spalte stehen, muss pSibling
380 			// auf den ersten Frame der naechsten Spalte zeigen, damit
381 			// der Inhalt der naechsten Spalte von InsertGroup richtig in den
382 			// neu angelegten pSect umgehaengt wird.
383 			SwColumnFrm *pCol = (SwColumnFrm*)pParent->GetUpper();
384 			while( !pSibling && 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
385 				pSibling = ((SwLayoutFrm*)((SwColumnFrm*)pCol)->Lower())->Lower();
386 			if( pSibling )
387 			{
388 				// Schlimmer noch: alle folgenden Spalteninhalte muessen
389 				// an die pSibling-Kette angehaengt werden, damit sie
390 				// mitgenommen werden.
391 				SwFrm *pTmp = pSibling;
392 				while ( 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
393 				{
394 					while ( pTmp->GetNext() )
395 						pTmp = pTmp->GetNext();
396 					SwFrm* pSave = ::SaveCntnt( pCol );
397                     ::RestoreCntnt( pSave, pSibling->GetUpper(), pTmp, true );
398                 }
399 			}
400 		}
401 		pParent = pSect;
402 		pSect = new SwSectionFrm( *((SwSectionFrm*)pParent)->GetSection(), pParent );
403 		// Wenn pParent in zwei Teile zerlegt wird, so muss sein Follow am
404 		// neuen, zweiten Teil angebracht werden.
405 		pSect->SetFollow( ((SwSectionFrm*)pParent)->GetFollow() );
406 		((SwSectionFrm*)pParent)->SetFollow( NULL );
407 		if( pSect->GetFollow() )
408 			pParent->_InvalidateSize();
409 
410 		InsertGroupBefore( pParent, pSibling, pSect );
411         pSect->Init();
412         (pSect->*fnRect->fnMakePos)( pSect->GetUpper(), pSect->GetPrev(), sal_True);
413 		if( !((SwLayoutFrm*)pParent)->Lower() )
414 		{
415 			SwSectionFrm::MoveCntntAndDelete( (SwSectionFrm*)pParent, sal_False );
416 			pParent = this;
417 		}
418 	}
419 	else
420 		InsertGroupBefore( pParent, pSibling, NULL );
421 
422 	_InvalidateAll();
423 	SwPageFrm *pPage = FindPageFrm();
424 	InvalidatePage( pPage );
425 
426 	if ( pSibling )
427 	{
428 		pSibling->_InvalidatePos();
429 		pSibling->_InvalidatePrt();
430 		if ( pSibling->IsCntntFrm() )
431 			pSibling->InvalidatePage( pPage );
432 	}
433 
434     SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
435     if( nFrmHeight )
436         pParent->Grow( nFrmHeight );
437 
438 	if ( GetPrev() )
439 	{
440 		if ( !IsFollow() )
441 		{
442 			GetPrev()->InvalidateSize();
443 			if ( GetPrev()->IsCntntFrm() )
444 				GetPrev()->InvalidatePage( pPage );
445 		}
446 	}
447 }
448 
449 
450 /*************************************************************************
451 |*
452 |*	SwSectionFrm::HasToBreak()
453 |*
454 |*  Hier wird entschieden, ob der this-SectionFrm den uebergebenen
455 |*  (Section)Frm aufbrechen soll oder nicht.
456 |*  Zunaechst werden uebergeordnete Bereiche immer aufgebrochen,
457 |*  spaeter koennte man es einstellbar machen.
458 |*
459 |*	Ersterstellung		AMA 12. Dec. 97
460 |*	Letzte Aenderung	AMA 12. Dec. 97
461 |*
462 |*************************************************************************/
463 
464 sal_Bool SwSectionFrm::HasToBreak( const SwFrm* pFrm ) const
465 {
466 	if( !pFrm->IsSctFrm() )
467 		return sal_False;
468 
469 	SwSectionFmt *pTmp = (SwSectionFmt*)GetFmt();
470 //	if( !pTmp->GetSect().GetValue() )
471 //		return sal_False;
472 
473 	const SwFrmFmt *pOtherFmt = ((SwSectionFrm*)pFrm)->GetFmt();
474 	do
475 	{
476 		pTmp = pTmp->GetParent();
477 		if( !pTmp )
478 			return sal_False;
479 		if( pTmp == pOtherFmt )
480 			return sal_True;
481 	} while( sal_True ); //	( pTmp->GetSect().GetValue() );
482 }
483 
484 /*************************************************************************
485 |*
486 |*	SwSectionFrm::MergeNext()
487 |*
488 |*	Ersterstellung		AMA 04. Dec. 97
489 |*	Letzte Aenderung	AMA 04. Dec. 97
490 |*
491 |*  Verschmilzt zwei SectionFrms, falls es sich um den
492 |*  gleichen Bereich handelt.
493 |*  Notwendig kann dies sein, wenn ein (Unter-)Bereich geloescht wird, der
494 |*  einen anderen in zwei Teile zerlegt hatte.
495 |*
496 |*************************************************************************/
497 
498 void SwSectionFrm::MergeNext( SwSectionFrm* pNxt )
499 {
500 	if( !pNxt->IsJoinLocked() && GetSection() == pNxt->GetSection() )
501 	{
502 		PROTOCOL( this, PROT_SECTION, ACT_MERGE, pNxt )
503 
504 		SwFrm* pTmp = ::SaveCntnt( pNxt );
505 		if( pTmp )
506 		{
507 			SwFrm* pLast = Lower();
508 			SwLayoutFrm* pLay = this;
509 			if( pLast )
510 			{
511 				while( pLast->GetNext() )
512 					pLast = pLast->GetNext();
513 				if( pLast->IsColumnFrm() )
514 				{   // Spalten jetzt mit BodyFrm
515 					pLay = (SwLayoutFrm*)((SwLayoutFrm*)pLast)->Lower();
516 					pLast = pLay->Lower();
517 					if( pLast )
518 						while( pLast->GetNext() )
519 							pLast = pLast->GetNext();
520 				}
521 			}
522             ::RestoreCntnt( pTmp, pLay, pLast, true );
523         }
524 		SetFollow( pNxt->GetFollow() );
525 		pNxt->SetFollow( NULL );
526 		pNxt->bIsFollow = sal_False;
527 		pNxt->Cut();
528 		delete pNxt;
529 		InvalidateSize();
530 	}
531 }
532 
533 /*************************************************************************
534 |*
535 |*	SwSectionFrm::SplitSect()
536 |*
537 |*	Ersterstellung		AMA 29. Apr. 99
538 |*	Letzte Aenderung	AMA 29. Apr. 99
539 |*
540 |*  Zerteilt einen SectionFrm in zwei Teile, der zweite Teil beginnt mit dem
541 |*  uebergebenen Frame.
542 |*  Benoetigt wird dies beim Einfuegen eines inneren Bereichs, weil innerhalb
543 |*  von Rahmen oder Tabellenzellen das MoveFwd nicht den erwuenschten Effekt
544 |*  haben kann.
545 |*
546 |*************************************************************************/
547 
548 sal_Bool SwSectionFrm::SplitSect( SwFrm* pFrm, sal_Bool bApres )
549 {
550 	ASSERT( pFrm, "SplitSect: Why?" );
551 	SwFrm* pOther = bApres ? pFrm->FindNext() : pFrm->FindPrev();
552 	if( !pOther )
553 		return sal_False;
554 	SwSectionFrm* pSect = pOther->FindSctFrm();
555     if( pSect != this )
556 		return sal_False;
557 	// Den Inhalt zur Seite stellen
558 	SwFrm* pSav = ::SaveCntnt( this, bApres ? pOther : pFrm );
559 	ASSERT( pSav, "SplitSect: What's on?" );
560 	if( pSav ) // Robust
561 	{	// Einen neuen SctFrm anlegen, nicht als Follow/Master
562         SwSectionFrm* pNew = new SwSectionFrm( *pSect->GetSection(), pSect );
563 		pNew->InsertBehind( pSect->GetUpper(), pSect );
564         pNew->Init();
565         SWRECTFN( this )
566         (pNew->*fnRect->fnMakePos)( NULL, pSect, sal_True );
567         // OD 25.03.2003 #108339# - restore content:
568         // determine layout frame for restoring content after the initialization
569         // of the section frame. In the section initialization the columns are
570         // created.
571         {
572             SwLayoutFrm* pLay = pNew;
573             // Search for last layout frame, e.g. for columned sections.
574             while( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
575                 pLay = (SwLayoutFrm*)pLay->Lower();
576             ::RestoreCntnt( pSav, pLay, NULL, true );
577         }
578         _InvalidateSize();
579         if( HasFollow() )
580         {
581             pNew->SetFollow( GetFollow() );
582             SetFollow( NULL );
583         }
584 		return sal_True;
585 	}
586 	return sal_False;
587 }
588 
589 /*************************************************************************
590 |*
591 |*	SwSectionFrm::MoveCntntAndDelete()
592 |*
593 |*	Ersterstellung		AMA 29. Jan 99
594 |*	Letzte Aenderung	AMA 29. Jan 99
595 |*
596 |*  MoveCntnt wird zur Zerstoerung eines SectionFrms wg. Aufhebung oder
597 |*  Verstecken des Bereichs gerufen, um den Inhalt umzuhaengen.
598 |*  Wenn der SectionFrm keinen anderen aufbrach, so wird der Inhalt in
599 |*  den Upper bewegt. Anderfalls wird der Inhalt in den anderen SectionFrm
600 |*  umgehaengt, dieser muss ggf. gemergt werden.
601 |*
602 |*************************************************************************/
603 // Wenn ein mehrspaltiger Bereich aufgehoben wird, muessen die ContentFrms
604 // invalidiert werden
605 
606 void lcl_InvalidateInfFlags( SwFrm* pFrm, sal_Bool bInva )
607 {
608 	while ( pFrm )
609 	{
610 		pFrm->InvalidateInfFlags();
611 		if( bInva )
612 		{
613 			pFrm->_InvalidatePos();
614 			pFrm->_InvalidateSize();
615 			pFrm->_InvalidatePrt();
616 		}
617 		if( pFrm->IsLayoutFrm() )
618 			lcl_InvalidateInfFlags( ((SwLayoutFrm*)pFrm)->GetLower(), sal_False );
619 		pFrm = pFrm->GetNext();
620 	}
621 }
622 
623 
624 //
625 // Works like SwCntntFrm::ImplGetNextCntntFrm, but starts with a LayoutFrm
626 //
627 SwCntntFrm* lcl_GetNextCntntFrm( const SwLayoutFrm* pLay, bool bFwd )
628 {
629     if ( bFwd )
630     {
631         if ( pLay->GetNext() && pLay->GetNext()->IsCntntFrm() )
632             return (SwCntntFrm*)pLay->GetNext();
633     }
634     else
635     {
636         if ( pLay->GetPrev() && pLay->GetPrev()->IsCntntFrm() )
637             return (SwCntntFrm*)pLay->GetPrev();
638     }
639 
640     // #100926#
641     const SwFrm* pFrm = pLay;
642     SwCntntFrm *pCntntFrm = 0;
643     sal_Bool bGoingUp = sal_True;
644     do {
645         const SwFrm *p = 0;
646         sal_Bool bGoingFwdOrBwd = sal_False, bGoingDown = sal_False;
647 
648         bGoingDown = !bGoingUp && ( 0 !=  ( p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0 ) );
649         if ( !bGoingDown )
650         {
651             bGoingFwdOrBwd = ( 0 != ( p = pFrm->IsFlyFrm() ?
652                                           ( bFwd ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink() ) :
653                                           ( bFwd ? pFrm->GetNext() :pFrm->GetPrev() ) ) );
654             if ( !bGoingFwdOrBwd )
655             {
656                 bGoingUp = (0 != (p = pFrm->GetUpper() ) );
657                 if ( !bGoingUp )
658                     return 0;
659             }
660         }
661 
662         bGoingUp = !( bGoingFwdOrBwd || bGoingDown );
663 
664         if( !bFwd && bGoingDown && p )
665             while ( p->GetNext() )
666                 p = p->GetNext();
667 
668         pFrm = p;
669     } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
670 
671     return pCntntFrm;
672 }
673 
674 #define FIRSTLEAF( pLayFrm ) ( ( pLayFrm->Lower() && pLayFrm->Lower()->IsColumnFrm() )\
675 					? pLayFrm->GetNextLayoutLeaf() \
676 					: pLayFrm )
677 
678 void SwSectionFrm::MoveCntntAndDelete( SwSectionFrm* pDel, sal_Bool bSave )
679 {
680 	sal_Bool bSize = pDel->Lower() && pDel->Lower()->IsColumnFrm();
681 	SwFrm* pPrv = pDel->GetPrev();
682 	SwLayoutFrm* pUp = pDel->GetUpper();
683     // OD 27.03.2003 #i12711# - initialize local pointer variables.
684     SwSectionFrm* pPrvSct = NULL;
685     SwSectionFrm* pNxtSct = NULL;
686     SwSectionFmt* pParent = static_cast<SwSectionFmt*>(pDel->GetFmt())->GetParent();
687 	if( pDel->IsInTab() && pParent )
688 	{
689 		SwTabFrm *pTab = pDel->FindTabFrm();
690 		// Wenn wir innerhalb einer Tabelle liegen, koennen wir nur Bereiche
691 		// aufgebrochen haben, die ebenfalls innerhalb liegen, nicht etwa
692 		// einen Bereich, der die gesamte Tabelle umfasst.
693 		if( pTab->IsInSct() && pParent == pTab->FindSctFrm()->GetFmt() )
694 			pParent = NULL;
695 	}
696 	// Wenn unser Format einen Parent besitzt, so haben wir vermutlich
697 	// einen anderen SectionFrm aufgebrochen, dies muss geprueft werden,
698 	// dazu besorgen wir uns zunaechst den vorhergehende und den nach-
699 	// folgenden CntntFrm, mal sehen, ob diese in SectionFrms liegen.
700     // OD 27.03.2003 #i12711# - check, if previous and next section belonging
701     // together and can be joined, *not* only if deleted section contains content.
702     if ( pParent )
703     {
704         SwFrm* pPrvCntnt = lcl_GetNextCntntFrm( pDel, false );
705         pPrvSct = pPrvCntnt ? pPrvCntnt->FindSctFrm() : NULL;
706         SwFrm* pNxtCntnt = lcl_GetNextCntntFrm( pDel, true );
707         pNxtSct = pNxtCntnt ? pNxtCntnt->FindSctFrm() : NULL;
708     }
709     else
710     {
711         pParent = NULL;
712         pPrvSct = pNxtSct = NULL;
713     }
714 
715 	// Jetzt wird der Inhalt beseite gestellt und der Frame zerstoert
716 	SwFrm *pSave = bSave ? ::SaveCntnt( pDel ) : NULL;
717 	sal_Bool bOldFtn = sal_True;
718 	if( pSave && pUp->IsFtnFrm() )
719 	{
720 		bOldFtn = ((SwFtnFrm*)pUp)->IsColLocked();
721 		((SwFtnFrm*)pUp)->ColLock();
722 	}
723 	pDel->DelEmpty( sal_True );
724 	delete pDel;
725 	if( pParent )
726 	{	// Hier wird die geeignete Einfuegeposition gesucht
727 		if( pNxtSct && pNxtSct->GetFmt() == pParent )
728 		{   // Hier koennen wir uns am Anfang einfuegen
729 			pUp = FIRSTLEAF( pNxtSct );
730 			pPrv = NULL;
731 			if( pPrvSct && !( pPrvSct->GetFmt() == pParent ) )
732 				pPrvSct = NULL; // damit nicht gemergt wird
733 		}
734 		else if( pPrvSct && pPrvSct->GetFmt() == pParent )
735 		{   // Wunderbar, hier koennen wir uns am Ende einfuegen
736 			pUp = pPrvSct;
737 			if( pUp->Lower() && pUp->Lower()->IsColumnFrm() )
738 			{
739                 pUp = static_cast<SwLayoutFrm*>(pUp->GetLastLower());
740                 // Der Body der letzten Spalte
741                 pUp = static_cast<SwLayoutFrm*>(pUp->Lower());
742 			}
743             // damit hinter dem letzten eingefuegt wird
744             pPrv = pUp->GetLastLower();
745             pPrvSct = NULL; // damit nicht gemergt wird
746 		}
747 		else
748 		{
749 			if( pSave )
750 			{	// Folgende Situationen: Vor und hinter dem zu loeschenden Bereich
751 				// ist entweder die Bereichsgrenze des umfassenden Bereichs oder
752 				// es schliesst ein anderer (Geschwister-)Bereich direkt an, der
753 				// vom gleichen Parent abgeleitet ist.
754 				// Dann gibt es (noch) keinen Teil unseres Parents, der den Inhalt
755 				// aufnehmen kann,also bauen wir ihn uns.
756                 pPrvSct = new SwSectionFrm( *pParent->GetSection(), pUp );
757 				pPrvSct->InsertBehind( pUp, pPrv );
758                 pPrvSct->Init();
759                 SWRECTFN( pUp )
760                 (pPrvSct->*fnRect->fnMakePos)( pUp, pPrv, sal_True );
761 				pUp = FIRSTLEAF( pPrvSct );
762 				pPrv = NULL;
763 			}
764 			pPrvSct = NULL; // damit nicht gemergt wird
765 		}
766 	}
767 	// Der Inhalt wird eingefuegt..
768 	if( pSave )
769 	{
770 		lcl_InvalidateInfFlags( pSave, bSize );
771         ::RestoreCntnt( pSave, pUp, pPrv, true );
772         pUp->FindPageFrm()->InvalidateCntnt();
773 		if( !bOldFtn )
774 			((SwFtnFrm*)pUp)->ColUnlock();
775 	}
776 	// jetzt koennen eventuell zwei Teile des uebergeordneten Bereich verschmelzen
777 	if( pPrvSct && !pPrvSct->IsJoinLocked() )
778 	{
779 		ASSERT( pNxtSct, "MoveCntnt: No Merge" );
780 		pPrvSct->MergeNext( pNxtSct );
781 	}
782 }
783 
784 void SwSectionFrm::MakeAll()
785 {
786 	if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
787 		return;
788 	if( !pSection ) // Durch DelEmpty
789 	{
790 		ASSERT( getRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
791 		if( !bValidPos )
792 		{
793             if( GetUpper() )
794             {
795                 SWRECTFN( GetUpper() )
796                 (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), sal_False );
797 			}
798         }
799 		bValidSize = bValidPos = bValidPrtArea = sal_True;
800 		return;
801 	}
802 	LockJoin();	//Ich lass mich nicht unterwegs vernichten.
803 
804 	while( GetNext() && GetNext() == GetFollow() )
805 	{
806 		const SwFrm* pFoll = GetFollow();
807 		MergeNext( (SwSectionFrm*)GetNext() );
808 		if( pFoll == GetFollow() )
809 			break;
810 	}
811 
812     // OD 2004-03-15 #116561# - In online layout join the follows, if section
813     // can grow.
814     const ViewShell *pSh = getRootFrm()->GetCurrShell();
815     if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
816          ( Grow( LONG_MAX, true ) > 0 ) )
817     {
818         while( GetFollow() )
819         {
820             const SwFrm* pFoll = GetFollow();
821             MergeNext( GetFollow() );
822             if( pFoll == GetFollow() )
823                 break;
824         }
825     }
826 
827 	// Ein Bereich mit Follow nimmt allen Platz bis zur Unterkante des Uppers
828 	// in Anspruch. Bewegt er sich, so kann seine Groesse zu- oder abnehmen...
829 	if( !bValidPos && ToMaximize( sal_False ) )
830 		bValidSize = sal_False;
831 
832 #if OSL_DEBUG_LEVEL > 1
833 	const SwFmtCol &rCol = GetFmt()->GetCol();
834     (void)rCol;
835 #endif
836 	SwLayoutFrm::MakeAll();
837 	UnlockJoin();
838 	if( pSection && IsSuperfluous() )
839 		DelEmpty( sal_False );
840 }
841 
842 sal_Bool SwSectionFrm::ShouldBwdMoved( SwLayoutFrm *, sal_Bool , sal_Bool & )
843 {
844 	ASSERT( sal_False, "Hups, wo ist meine Tarnkappe?" );
845 	return sal_False;
846 }
847 
848 const SwSectionFmt* SwSectionFrm::_GetEndSectFmt() const
849 {
850 	const SwSectionFmt *pFmt = pSection->GetFmt();
851 	while( !pFmt->GetEndAtTxtEnd().IsAtEnd() )
852 	{
853 		if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
854 			pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
855 		else
856 			return NULL;
857 	}
858 	return pFmt;
859 }
860 
861 void lcl_FindCntntFrm( SwCntntFrm* &rpCntntFrm, SwFtnFrm* &rpFtnFrm,
862 	SwFrm* pFrm, sal_Bool &rbChkFtn )
863 {
864 	if( pFrm )
865 	{
866 		while( pFrm->GetNext() )
867 			pFrm = pFrm->GetNext();
868 		while( !rpCntntFrm && pFrm )
869 		{
870 			if( pFrm->IsCntntFrm() )
871 				rpCntntFrm = (SwCntntFrm*)pFrm;
872 			else if( pFrm->IsLayoutFrm() )
873 			{
874 				if( pFrm->IsFtnFrm() )
875 				{
876 					if( rbChkFtn )
877 					{
878 						rpFtnFrm = (SwFtnFrm*)pFrm;
879 						rbChkFtn = rpFtnFrm->GetAttr()->GetFtn().IsEndNote();
880 					}
881 				}
882 				else
883 					lcl_FindCntntFrm( rpCntntFrm, rpFtnFrm,
884 						((SwLayoutFrm*)pFrm)->Lower(), rbChkFtn );
885 			}
886 			pFrm = pFrm->GetPrev();
887 		}
888 	}
889 }
890 
891 SwCntntFrm *SwSectionFrm::FindLastCntnt( sal_uInt8 nMode )
892 {
893 	SwCntntFrm *pRet = NULL;
894 	SwFtnFrm *pFtnFrm = NULL;
895 	SwSectionFrm *pSect = this;
896 	if( nMode )
897 	{
898 		const SwSectionFmt *pFmt = IsEndnAtEnd() ? GetEndSectFmt() :
899 			  					   pSection->GetFmt();
900 		do {
901 			while( pSect->HasFollow() )
902 				pSect = pSect->GetFollow();
903 			SwFrm* pTmp = pSect->FindNext();
904 			while( pTmp && pTmp->IsSctFrm() &&
905 				   !((SwSectionFrm*)pTmp)->GetSection() )
906 				pTmp = pTmp->FindNext();
907 			if( pTmp && pTmp->IsSctFrm() &&
908 				((SwSectionFrm*)pTmp)->IsDescendantFrom( pFmt ) )
909 				pSect = (SwSectionFrm*)pTmp;
910 			else
911 				break;
912 		} while( sal_True );
913 	}
914 	sal_Bool bFtnFound = nMode == FINDMODE_ENDNOTE;
915 	do
916 	{
917 		lcl_FindCntntFrm( pRet, pFtnFrm, pSect->Lower(), bFtnFound );
918 		if( pRet || !pSect->IsFollow() || !nMode ||
919 			( FINDMODE_MYLAST == nMode && this == pSect ) )
920 			break;
921         pSect = pSect->FindMaster();
922 	} while( pSect );
923 	if( ( nMode == FINDMODE_ENDNOTE ) && pFtnFrm )
924 		pRet = pFtnFrm->ContainsCntnt();
925 	return pRet;
926 }
927 
928 sal_Bool SwSectionFrm::CalcMinDiff( SwTwips& rMinDiff ) const
929 {
930 	if( ToMaximize( sal_True ) )
931 	{
932         SWRECTFN( this )
933         rMinDiff = (GetUpper()->*fnRect->fnGetPrtBottom)();
934         rMinDiff = (Frm().*fnRect->fnBottomDist)( rMinDiff );
935         return sal_True;
936 	}
937 	return sal_False;
938 }
939 
940 /*************************************************************************
941  *
942  * 	SwSectionFrm::CollectEndnotes(  )
943  *
944  *	Ersterstellung		AMA 03. Nov 99
945  *	Letzte Aenderung	AMA 03. Nov 99
946  *
947  *  CollectEndnotes looks for endnotes in the sectionfrm and his follows,
948  *  the endnotes will cut off the layout and put into the array.
949  *  If the first endnote is not a master-SwFtnFrm, the whole sectionfrm
950  *  contains only endnotes and it is not necessary to collect them.
951  *
952  *************************************************************************/
953 
954 SwFtnFrm* lcl_FindEndnote( SwSectionFrm* &rpSect, sal_Bool &rbEmpty,
955 	SwLayouter *pLayouter )
956 {
957 	// if rEmpty is set, the rpSect is already searched
958 	SwSectionFrm* pSect = rbEmpty ? rpSect->GetFollow() : rpSect;
959 	while( pSect )
960 	{
961        ASSERT( (pSect->Lower() && pSect->Lower()->IsColumnFrm()) || pSect->GetUpper()->IsFtnFrm(),
962                 "InsertEndnotes: Where's my column?" );
963 
964         // i73332: Columned section in endnote
965         SwColumnFrm* pCol = 0;
966         if(pSect->Lower() && pSect->Lower()->IsColumnFrm())
967             pCol = (SwColumnFrm*)pSect->Lower();
968 
969         while( pCol ) // check all columns
970 		{
971 			SwFtnContFrm* pFtnCont = pCol->FindFtnCont();
972 			if( pFtnCont )
973 			{
974 				SwFtnFrm* pRet = (SwFtnFrm*)pFtnCont->Lower();
975 				while( pRet ) // look for endnotes
976 				{
977 					if( pRet->GetAttr()->GetFtn().IsEndNote() )
978 					{
979 						if( pRet->GetMaster() )
980 						{
981 							if( pLayouter )
982 								pLayouter->CollectEndnote( pRet );
983 							else
984 								return 0;
985 						}
986 						else
987 							return pRet; // Found
988 					}
989 					pRet = (SwFtnFrm*)pRet->GetNext();
990 				}
991 			}
992 			pCol = (SwColumnFrm*)pCol->GetNext();
993         }
994 		rpSect = pSect;
995 		pSect = pLayouter ? pSect->GetFollow() : NULL;
996 		rbEmpty = sal_True;
997 	}
998 	return NULL;
999 }
1000 
1001 void lcl_ColumnRefresh( SwSectionFrm* pSect, sal_Bool bFollow )
1002 {
1003 	while( pSect )
1004 	{
1005 		sal_Bool bOldLock = pSect->IsColLocked();
1006 		pSect->ColLock();
1007 		if( pSect->Lower() && pSect->Lower()->IsColumnFrm() )
1008 		{
1009 			SwColumnFrm *pCol = (SwColumnFrm*)pSect->Lower();
1010 			do
1011 			{	pCol->_InvalidateSize();
1012 				pCol->_InvalidatePos();
1013 				((SwLayoutFrm*)pCol)->Lower()->_InvalidateSize();
1014 				pCol->Calc();   // calculation of column and
1015 				((SwLayoutFrm*)pCol)->Lower()->Calc();  // body
1016 				pCol = (SwColumnFrm*)pCol->GetNext();
1017 			} while ( pCol );
1018 		}
1019 		if( !bOldLock )
1020 			pSect->ColUnlock();
1021 		if( bFollow )
1022 			pSect = pSect->GetFollow();
1023 		else
1024 			pSect = NULL;
1025 	}
1026 }
1027 
1028 void SwSectionFrm::CollectEndnotes( SwLayouter* pLayouter )
1029 {
1030 	ASSERT( IsColLocked(), "CollectEndnotes: You love the risk?" );
1031     // i73332: Section in footnode does not have columns!
1032     ASSERT( (Lower() && Lower()->IsColumnFrm()) || GetUpper()->IsFtnFrm(), "Where's my column?" );
1033 
1034 	SwSectionFrm* pSect = this;
1035 	SwFtnFrm* pFtn;
1036 	sal_Bool bEmpty = sal_False;
1037 	// pSect is the last sectionfrm without endnotes or the this-pointer
1038 	// the first sectionfrm with endnotes may be destroyed, when the endnotes
1039 	// is cutted
1040 	while( 0 != (pFtn = lcl_FindEndnote( pSect, bEmpty, pLayouter )) )
1041 		pLayouter->CollectEndnote( pFtn );
1042 	if( pLayouter->HasEndnotes() )
1043 		lcl_ColumnRefresh( this, sal_True );
1044 }
1045 
1046 /*************************************************************************
1047 |*
1048 |*	SwSectionFrm::_CheckClipping( sal_Bool bGrow, sal_Bool bMaximize )
1049 |*
1050 |*	Beschreibung:		Passt die Groesse an die Umgebung an.
1051 |*  	Wer einen Follow oder Fussnoten besitzt, soll bis zur Unterkante
1052 |*      des Uppers gehen (bMaximize).
1053 |*		Niemand darf ueber den Upper hinausgehen, ggf. darf man versuchen (bGrow)
1054 |*		seinen Upper zu growen.
1055 |*      Wenn die Groesse veraendert werden musste, wird der Inhalt kalkuliert.
1056 |*
1057 |*************************************************************************/
1058 
1059 /// OD 18.09.2002 #100522#
1060 /// perform calculation of content, only if height has changed.
1061 void SwSectionFrm::_CheckClipping( sal_Bool bGrow, sal_Bool bMaximize )
1062 {
1063     SWRECTFN( this )
1064     long nDiff;
1065     SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1066 	if( bGrow && ( !IsInFly() || !GetUpper()->IsColBodyFrm() ||
1067 				   !FindFlyFrm()->IsLocked() ) )
1068 	{
1069         nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine );
1070         if( !bMaximize )
1071             nDiff += Undersize();
1072         if( nDiff > 0 )
1073         {
1074             long nAdd = GetUpper()->Grow( nDiff );
1075             if( bVert && !bRev )
1076                 nDeadLine -= nAdd;
1077             else
1078                 nDeadLine += nAdd;
1079         }
1080 	}
1081     nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine );
1082     SetUndersized( !bMaximize && nDiff >= 0 );
1083     const bool bCalc = ( IsUndersized() || bMaximize ) &&
1084                        ( nDiff ||
1085                          (Prt().*fnRect->fnGetTop)() > (Frm().*fnRect->fnGetHeight)() );
1086     // OD 03.11.2003 #i19737# - introduce local variable <bExtraCalc> to indicate
1087     // that a calculation has to be done beside the value of <bCalc>.
1088     bool bExtraCalc = false;
1089     if( !bCalc && !bGrow && IsAnyNoteAtEnd() && !IsInFtn() )
1090 	{
1091 		SwSectionFrm *pSect = this;
1092 		sal_Bool bEmpty = sal_False;
1093 		SwLayoutFrm* pFtn = IsEndnAtEnd() ?
1094 			lcl_FindEndnote( pSect, bEmpty, NULL ) : NULL;
1095 		if( pFtn )
1096 		{
1097 			pFtn = pFtn->FindFtnBossFrm();
1098 			SwFrm* pTmp = FindLastCntnt( FINDMODE_LASTCNT );
1099             // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
1100             if ( pTmp && pFtn->IsBefore( pTmp->FindFtnBossFrm() ) )
1101                 bExtraCalc = true;
1102 		}
1103 		else if( GetFollow() && !GetFollow()->ContainsAny() )
1104             bExtraCalc = true;
1105 	}
1106     if ( bCalc || bExtraCalc )
1107 	{
1108         nDiff = (*fnRect->fnYDiff)( nDeadLine, (Frm().*fnRect->fnGetTop)() );
1109         if( nDiff < 0 )
1110         {
1111             nDiff = 0;
1112             nDeadLine = (Frm().*fnRect->fnGetTop)();
1113         }
1114         const Size aOldSz( Prt().SSize() );
1115         long nTop = (this->*fnRect->fnGetTopMargin)();
1116         (Frm().*fnRect->fnSetBottom)( nDeadLine );
1117         nDiff = (Frm().*fnRect->fnGetHeight)();
1118         if( nTop > nDiff )
1119             nTop = nDiff;
1120         (this->*fnRect->fnSetYMargins)( nTop, 0 );
1121 
1122         // OD 18.09.2002 #100522#
1123         // Determine, if height has changed.
1124         // Note: In vertical layout the height equals the width value.
1125         bool bHeightChanged = bVert ?
1126                             (aOldSz.Width() != Prt().Width()) :
1127                             (aOldSz.Height() != Prt().Height());
1128         // Wir haben zu guter Letzt noch einmal die Hoehe geaendert,
1129 		// dann wird das innere Layout (Columns) kalkuliert und
1130 		// der Inhalt ebenfalls.
1131         // OD 18.09.2002 #100522#
1132         // calculate content, only if height has changed.
1133         // OD 03.11.2003 #i19737# - restriction of content calculation too strong.
1134         // If an endnote has an incorrect position or a follow section contains
1135         // no content except footnotes/endnotes, the content has also been calculated.
1136         if ( ( bHeightChanged || bExtraCalc ) && Lower() )
1137 		{
1138 			if( Lower()->IsColumnFrm() )
1139 			{
1140 				lcl_ColumnRefresh( this, sal_False );
1141                 ::CalcCntnt( this );
1142 			}
1143 			else
1144 			{
1145 				ChgLowersProp( aOldSz );
1146 				if( !bMaximize && !IsCntntLocked() )
1147 					::CalcCntnt( this );
1148 			}
1149 		}
1150 	}
1151 }
1152 
1153 void SwSectionFrm::SimpleFormat()
1154 {
1155 	if ( IsJoinLocked() || IsColLocked() )
1156 		return;
1157 	// ASSERT( pFollow, "SimpleFormat: Follow required" );
1158 	LockJoin();
1159     SWRECTFN( this )
1160     if( GetPrev() || GetUpper() )
1161 	{
1162         // --> OD 2009-09-28 #b6882166#
1163         // assure notifications on position changes.
1164         const SwLayNotify aNotify( this );
1165         // <--
1166         (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), sal_False );
1167 		bValidPos = sal_True;
1168 	}
1169     SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1170     // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
1171     // order to get calculated lowers, not only if there space left in its upper.
1172     if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) >= 0 )
1173 	{
1174         (Frm().*fnRect->fnSetBottom)( nDeadLine );
1175         long nHeight = (Frm().*fnRect->fnGetHeight)();
1176         long nTop = CalcUpperSpace();
1177         if( nTop > nHeight )
1178             nTop = nHeight;
1179         (this->*fnRect->fnSetYMargins)( nTop, 0 );
1180 	}
1181     lcl_ColumnRefresh( this, sal_False );
1182 	UnlockJoin();
1183 }
1184 
1185 // --> OD 2005-01-11 #i40147# - helper class to perform extra section format
1186 // to position anchored objects and to keep the position of whose objects locked.
1187 class ExtraFormatToPositionObjs
1188 {
1189     private:
1190         SwSectionFrm* mpSectFrm;
1191         bool mbExtraFormatPerformed;
1192 
1193     public:
1194         ExtraFormatToPositionObjs( SwSectionFrm& _rSectFrm)
1195             : mpSectFrm( &_rSectFrm ),
1196               mbExtraFormatPerformed( false )
1197         {}
1198 
1199         ~ExtraFormatToPositionObjs()
1200         {
1201             if ( mbExtraFormatPerformed )
1202             {
1203                 // release keep locked position of lower floating screen objects
1204                 SwPageFrm* pPageFrm = mpSectFrm->FindPageFrm();
1205                 SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
1206                 if ( pObjs )
1207                 {
1208                     sal_uInt32 i = 0;
1209                     for ( i = 0; i < pObjs->Count(); ++i )
1210                     {
1211                         SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1212 
1213                         if ( mpSectFrm->IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
1214                         {
1215                             pAnchoredObj->SetKeepPosLocked( false );
1216                         }
1217                     }
1218                 }
1219             }
1220         }
1221 
1222         // --> OD 2008-06-20 #i81555#
1223         void InitObjs( SwFrm& rFrm )
1224         {
1225             SwSortedObjs* pObjs = rFrm.GetDrawObjs();
1226             if ( pObjs )
1227             {
1228                 sal_uInt32 i = 0;
1229                 for ( i = 0; i < pObjs->Count(); ++i )
1230                 {
1231                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1232 
1233                     pAnchoredObj->UnlockPosition();
1234                     pAnchoredObj->SetClearedEnvironment( false );
1235                 }
1236             }
1237             SwLayoutFrm* pLayoutFrm = dynamic_cast<SwLayoutFrm*>(&rFrm);
1238             if ( pLayoutFrm != 0 )
1239             {
1240                 SwFrm* pLowerFrm = pLayoutFrm->GetLower();
1241                 while ( pLowerFrm != 0 )
1242                 {
1243                     InitObjs( *pLowerFrm );
1244 
1245                     pLowerFrm = pLowerFrm->GetNext();
1246                 }
1247             }
1248         }
1249         // <--
1250 
1251         void FormatSectionToPositionObjs()
1252         {
1253             // perform extra format for multi-columned section.
1254             if ( mpSectFrm->Lower() && mpSectFrm->Lower()->IsColumnFrm() &&
1255                  mpSectFrm->Lower()->GetNext() )
1256             {
1257                 // grow section till bottom of printing area of upper frame
1258                 SWRECTFN( mpSectFrm );
1259                 SwTwips nTopMargin = (mpSectFrm->*fnRect->fnGetTopMargin)();
1260                 Size aOldSectPrtSize( mpSectFrm->Prt().SSize() );
1261                 SwTwips nDiff = (mpSectFrm->Frm().*fnRect->fnBottomDist)(
1262                                         (mpSectFrm->GetUpper()->*fnRect->fnGetPrtBottom)() );
1263                 (mpSectFrm->Frm().*fnRect->fnAddBottom)( nDiff );
1264                 (mpSectFrm->*fnRect->fnSetYMargins)( nTopMargin, 0 );
1265                 // --> OD 2006-05-08 #i59789#
1266                 // suppress formatting, if printing area of section is too narrow
1267                 if ( (mpSectFrm->Prt().*fnRect->fnGetHeight)() <= 0 )
1268                 {
1269                     return;
1270                 }
1271                 // <--
1272                 mpSectFrm->ChgLowersProp( aOldSectPrtSize );
1273 
1274                 // format column frames and its body and footnote container
1275                 SwColumnFrm* pColFrm = static_cast<SwColumnFrm*>(mpSectFrm->Lower());
1276                 while ( pColFrm )
1277                 {
1278                     pColFrm->Calc();
1279                     pColFrm->Lower()->Calc();
1280                     if ( pColFrm->Lower()->GetNext() )
1281                     {
1282                         pColFrm->Lower()->GetNext()->Calc();
1283                     }
1284 
1285                     pColFrm = static_cast<SwColumnFrm*>(pColFrm->GetNext());
1286                 }
1287 
1288                 // unlock position of lower floating screen objects for the extra format
1289                 // --> OD 2008-06-20 #i81555#
1290                 // Section frame can already have changed the page and its content
1291                 // can still be on the former page.
1292                 // Thus, initialize objects via lower-relationship
1293                 InitObjs( *mpSectFrm );
1294                 // <--
1295 
1296                 // format content - first with collecting its foot-/endnotes before content
1297                 // format, second without collecting its foot-/endnotes.
1298                 ::CalcCntnt( mpSectFrm );
1299                 ::CalcCntnt( mpSectFrm, true );
1300 
1301                 // keep locked position of lower floating screen objects
1302                 SwPageFrm* pPageFrm = mpSectFrm->FindPageFrm();
1303                 SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
1304                 if ( pObjs )
1305                 {
1306                     sal_uInt32 i = 0;
1307                     for ( i = 0; i < pObjs->Count(); ++i )
1308                     {
1309                         SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1310 
1311                         if ( mpSectFrm->IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
1312                         {
1313                             pAnchoredObj->SetKeepPosLocked( true );
1314                         }
1315                     }
1316                 }
1317 
1318                 mbExtraFormatPerformed = true;
1319             }
1320         }
1321 };
1322 
1323 /*************************************************************************
1324 |*
1325 |*	SwSectionFrm::Format()
1326 |*
1327 |*	Beschreibung:		"Formatiert" den Frame; Frm und PrtArea.
1328 |*	Ersterstellung		AMA 03. Dec. 97
1329 |* 	Letzte Aenderung	MA 09. Oct. 98
1330 |*
1331 |*************************************************************************/
1332 
1333 void SwSectionFrm::Format( const SwBorderAttrs *pAttr )
1334 {
1335 	if( !pSection ) // Durch DelEmpty
1336 	{
1337 		ASSERT( getRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
1338 		bValidSize = bValidPos = bValidPrtArea = sal_True;
1339 		return;
1340 	}
1341     SWRECTFN( this )
1342 	if ( !bValidPrtArea )
1343 	{
1344 		PROTOCOL( this, PROT_PRTAREA, 0, 0 )
1345 		bValidPrtArea = sal_True;
1346 		SwTwips nUpper = CalcUpperSpace();
1347 
1348         // #109700# LRSpace for sections
1349         const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
1350         (this->*fnRect->fnSetXMargins)( rLRSpace.GetLeft(), rLRSpace.GetRight() );
1351 
1352         if( nUpper != (this->*fnRect->fnGetTopMargin)() )
1353 		{
1354 			bValidSize = sal_False;
1355 			SwFrm* pOwn = ContainsAny();
1356 			if( pOwn )
1357 				pOwn->_InvalidatePos();
1358 		}
1359         (this->*fnRect->fnSetYMargins)( nUpper, 0 );
1360 	}
1361 
1362 	if ( !bValidSize )
1363 	{
1364 		PROTOCOL_ENTER( this, PROT_SIZE, 0, 0 )
1365         const long nOldHeight = (Frm().*fnRect->fnGetHeight)();
1366 		sal_Bool bOldLock = IsColLocked();
1367 		ColLock();
1368 
1369 		bValidSize = sal_True;
1370 
1371         //die Groesse wird nur dann vom Inhalt bestimmt, wenn der SectFrm
1372 		//keinen Follow hat. Anderfalls fuellt er immer den Upper bis
1373 		//zur Unterkante aus. Fuer den Textfluss ist nicht er, sondern sein
1374 		//Inhalt selbst verantwortlich.
1375 		sal_Bool bMaximize = ToMaximize( sal_False );
1376 
1377         // OD 2004-05-17 #i28701# - If the wrapping style has to be considered
1378         // on object positioning, an extra formatting has to be performed
1379         // to determine the correct positions the floating screen objects.
1380         // --> OD 2005-01-11 #i40147#
1381         // use new helper class <ExtraFormatToPositionObjs>.
1382         // This class additionally keep the locked position of the objects
1383         // and releases this position lock keeping on destruction.
1384         ExtraFormatToPositionObjs aExtraFormatToPosObjs( *this );
1385         if ( !bMaximize &&
1386              GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
1387              !GetFmt()->GetBalancedColumns().GetValue() )
1388         {
1389             aExtraFormatToPosObjs.FormatSectionToPositionObjs();
1390         }
1391         // <--
1392 
1393         // Column widths have to be adjusted before calling _CheckClipping.
1394         // _CheckClipping can cause the formatting of the lower frames
1395         // which still have a width of 0.
1396         const sal_Bool bHasColumns = Lower() && Lower()->IsColumnFrm();
1397         if ( bHasColumns && Lower()->GetNext() )
1398             AdjustColumns( 0, sal_False );
1399 
1400 		if( GetUpper() )
1401 		{
1402             long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
1403             (aFrm.*fnRect->fnSetWidth)( nWidth );
1404 
1405             // #109700# LRSpace for sections
1406             const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
1407             (aPrt.*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() -
1408                                         rLRSpace.GetRight() );
1409 
1410             // OD 15.10.2002 #103517# - allow grow in online layout
1411             // Thus, set <..IsBrowseMode()> as parameter <bGrow> on calling
1412             // method <_CheckClipping(..)>.
1413             const ViewShell *pSh = getRootFrm()->GetCurrShell();
1414             _CheckClipping( pSh && pSh->GetViewOptions()->getBrowseMode(), bMaximize );
1415 			bMaximize = ToMaximize( sal_False );
1416 			bValidSize = sal_True;
1417 		}
1418 
1419         //Breite der Spalten pruefen und ggf. einstellen.
1420         if ( bHasColumns && ! Lower()->GetNext() && bMaximize )
1421             ((SwColumnFrm*)Lower())->Lower()->Calc();
1422 
1423 		if ( !bMaximize )
1424 		{
1425             SwTwips nRemaining = (this->*fnRect->fnGetTopMargin)();
1426 			SwFrm *pFrm = pLower;
1427 			if( pFrm )
1428 			{
1429 				if( pFrm->IsColumnFrm() && pFrm->GetNext() )
1430 				{
1431                     // --> OD 2006-05-08 #i61435#
1432                     // suppress formatting, if upper frame has height <= 0
1433                     if ( (GetUpper()->Frm().*fnRect->fnGetHeight)() > 0 )
1434                     {
1435                         FormatWidthCols( *pAttr, nRemaining, MINLAY );
1436                     }
1437                     // <--
1438                     // --> OD 2006-01-04 #126020# - adjust check for empty section
1439                     // --> OD 2006-02-01 #130797# - correct fix #126020#
1440                     while( HasFollow() && !GetFollow()->ContainsCntnt() &&
1441                            !GetFollow()->ContainsAny( true ) )
1442                     // <--
1443 					{
1444 						SwFrm* pOld = GetFollow();
1445 						GetFollow()->DelEmpty( sal_False );
1446 						if( pOld == GetFollow() )
1447 							break;
1448 					}
1449 					bMaximize = ToMaximize( sal_False );
1450                     nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
1451 				}
1452 				else
1453 				{
1454 					if( pFrm->IsColumnFrm() )
1455 					{
1456 						pFrm->Calc();
1457 						pFrm = ((SwColumnFrm*)pFrm)->Lower();
1458 						pFrm->Calc();
1459 						pFrm = ((SwLayoutFrm*)pFrm)->Lower();
1460 						CalcFtnCntnt();
1461 					}
1462 					// Wenn wir in einem spaltigen Rahmen stehen und dieser
1463 					// gerade im FormatWidthCols ein CalcCntnt ruft, muss
1464 					// unser Inhalt ggf. kalkuliert werden.
1465 					if( pFrm && !pFrm->IsValid() && IsInFly() &&
1466 						FindFlyFrm()->IsColLocked() )
1467 						::CalcCntnt( this );
1468 					nRemaining += InnerHeight();
1469 					bMaximize = HasFollow();
1470 				}
1471 			}
1472 
1473             SwTwips nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining;
1474 			if( nDiff < 0)
1475 			{
1476                 SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1477 				{
1478                     long nBottom = (Frm().*fnRect->fnGetBottom)();
1479                     nBottom = (*fnRect->fnYInc)( nBottom, -nDiff );
1480                     long nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine );
1481                     if( nTmpDiff > 0 )
1482 					{
1483                         nTmpDiff = GetUpper()->Grow( nTmpDiff, sal_True );
1484                         nDeadLine = (*fnRect->fnYInc)( nDeadLine, nTmpDiff );
1485                         nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine );
1486                         if( nTmpDiff > 0 )
1487                             nDiff += nTmpDiff;
1488 						if( nDiff > 0 )
1489 							nDiff = 0;
1490 					}
1491 				}
1492 			}
1493 			if( nDiff )
1494 			{
1495                 long nTmp = nRemaining - (Frm().*fnRect->fnGetHeight)();
1496                 long nTop = (this->*fnRect->fnGetTopMargin)();
1497                 (Frm().*fnRect->fnAddBottom)( nTmp );
1498                 (this->*fnRect->fnSetYMargins)( nTop, 0 );
1499 				InvalidateNextPos();
1500 				if( pLower && ( !pLower->IsColumnFrm() || !pLower->GetNext() ) )
1501 				{
1502 					// Wenn ein einspaltiger Bereich gerade den Platz geschaffen
1503 					// hat, den sich die "undersized" Absaetze gewuenscht haben,
1504 					// muessen diese invalidiert und kalkuliert werden, damit
1505 					// sie diesen ausfuellen.
1506 					pFrm = pLower;
1507 					if( pFrm->IsColumnFrm() )
1508 					{
1509 						pFrm->_InvalidateSize();
1510 						pFrm->_InvalidatePos();
1511 						pFrm->Calc();
1512 						pFrm = ((SwColumnFrm*)pFrm)->Lower();
1513 						pFrm->Calc();
1514 						pFrm = ((SwLayoutFrm*)pFrm)->Lower();
1515 						CalcFtnCntnt();
1516 					}
1517 					sal_Bool bUnderSz = sal_False;
1518 					while( pFrm )
1519 					{
1520 						if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
1521 						{
1522 							pFrm->Prepare( PREP_ADJUST_FRM );
1523 							bUnderSz = sal_True;
1524 						}
1525 						pFrm = pFrm->GetNext();
1526 					}
1527 					if( bUnderSz && !IsCntntLocked() )
1528 						::CalcCntnt( this );
1529 				}
1530 			}
1531 		}
1532 
1533 		//Unterkante des Uppers nicht ueberschreiten. Fuer Sections mit
1534 		//Follows die Unterkante auch nicht unterschreiten.
1535 		if ( GetUpper() )
1536 			_CheckClipping( sal_True, bMaximize );
1537 		if( !bOldLock )
1538 			ColUnlock();
1539         long nDiff = nOldHeight - (Frm().*fnRect->fnGetHeight)();
1540         if( nDiff > 0 )
1541 		{
1542 			if( !GetNext() )
1543 				SetRetouche(); // Dann muessen wir die Retusche selbst uebernehmen
1544             if( GetUpper() && !GetUpper()->IsFooterFrm() )
1545                 GetUpper()->Shrink( nDiff );
1546 		}
1547 		if( IsUndersized() )
1548 			bValidPrtArea = sal_True;
1549     }
1550 }
1551 
1552 /*************************************************************************
1553 |*
1554 |*	SwFrm::GetNextSctLeaf()
1555 |*
1556 |*	Beschreibung		Liefert das naechste Layoutblatt in das der	Frame
1557 |* 		gemoved werden kann.
1558 |* 		Neue Seiten werden nur dann erzeugt, wenn der Parameter sal_True ist.
1559 |*	Ersterstellung		AMA 07. Jan. 98
1560 |*	Letzte Aenderung	AMA 07. Jan. 98
1561 |*
1562 |*************************************************************************/
1563 
1564 
1565 SwLayoutFrm *SwFrm::GetNextSctLeaf( MakePageType eMakePage )
1566 {
1567 	//Achtung: Geschachtelte Bereiche werden zur Zeit nicht unterstuetzt.
1568 
1569 	PROTOCOL_ENTER( this, PROT_LEAF, ACT_NEXT_SECT, GetUpper()->FindSctFrm() )
1570 
1571 	// Abkuerzungen fuer spaltige Bereiche, wenn wir noch nicht in der letzten Spalte sind.
1572 	// Koennen wir in die naechste Spalte des Bereichs rutschen?
1573 	if( IsColBodyFrm() && GetUpper()->GetNext() )
1574 		return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetNext())->Lower();
1575 	if( GetUpper()->IsColBodyFrm() && GetUpper()->GetUpper()->GetNext() )
1576 		return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetUpper()->GetNext())->Lower();
1577 	// Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann
1578 	// nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette zuschlagen muessen
1579 	if( GetUpper()->IsInTab() || FindFooterOrHeader() )
1580 		return 0;
1581 
1582 //MA 03. Feb. 99: Warum GetUpper()? Das knallt mit Buch.sgl weil im
1583 //FlyAtCnt::MakeFlyPos ein Orient der SectionFrm ist und auf diesen ein
1584 //GetLeaf gerufen wird.
1585 //	SwSectionFrm *pSect = GetUpper()->FindSctFrm();
1586 	SwSectionFrm *pSect = FindSctFrm();
1587 	sal_Bool bWrongPage = sal_False;
1588 	ASSERT( pSect, "GetNextSctLeaf: Missing SectionFrm" );
1589 
1590 	// Hier eine Abkuerzung fuer Bereiche mit Follows,
1591 	// dieser kann akzeptiert werden, wenn keine Spalten oder Seiten (ausser Dummyseiten)
1592 	// dazwischen liegen.
1593 	// Bei verketteten Rahmen und ind Fussnoten wuerde die Abkuerzung noch aufwendiger
1594 	if( pSect->HasFollow() && pSect->IsInDocBody() )
1595 	{
1596 		if( pSect->GetFollow() == pSect->GetNext() )
1597 		{
1598 			SwPageFrm *pPg = pSect->GetFollow()->FindPageFrm();
1599 			if( WrongPageDesc( pPg ) )
1600 				bWrongPage = sal_True;
1601 			else
1602 				return FIRSTLEAF( pSect->GetFollow() );
1603 		}
1604 		else
1605 		{
1606 			SwFrm* pTmp;
1607 			if( !pSect->GetUpper()->IsColBodyFrm() ||
1608 				0 == ( pTmp = pSect->GetUpper()->GetUpper()->GetNext() ) )
1609 				pTmp = pSect->FindPageFrm()->GetNext();
1610 			if( pTmp ) // ist jetzt die naechste Spalte oder Seite
1611 			{
1612 				SwFrm* pTmpX = pTmp;
1613 				if( pTmp->IsPageFrm() && ((SwPageFrm*)pTmp)->IsEmptyPage() )
1614 					pTmp = pTmp->GetNext(); // Dummyseiten ueberspringen
1615 				SwFrm *pUp = pSect->GetFollow()->GetUpper();
1616 				// pUp wird die Spalte, wenn der Follow in einer "nicht ersten" Spalte
1617 				// liegt, ansonsten die Seite:
1618 				if( !pUp->IsColBodyFrm() ||
1619 					!( pUp = pUp->GetUpper() )->GetPrev() )
1620 					pUp = pUp->FindPageFrm();
1621 				// Jetzt muessen pUp und pTmp die gleiche Seite/Spalte sein,
1622 				// sonst liegen Seiten oder Spalten zwischen Master und Follow.
1623 				if( pUp == pTmp || pUp->GetNext() == pTmpX )
1624 				{
1625 					SwPageFrm* pNxtPg = pUp->IsPageFrm() ?
1626 										(SwPageFrm*)pUp : pUp->FindPageFrm();
1627 					if( WrongPageDesc( pNxtPg ) )
1628 						bWrongPage = sal_True;
1629 					else
1630 						return FIRSTLEAF( pSect->GetFollow() );
1631 				}
1632 			}
1633 		}
1634 	}
1635 
1636 	// Immer im gleichen Bereich landen: Body wieder in Body etc.
1637 	const sal_Bool bBody = IsInDocBody();
1638 	const sal_Bool bFtnPage = FindPageFrm()->IsFtnPage();
1639 
1640 	SwLayoutFrm *pLayLeaf;
1641 	// Eine Abkuerzung fuer TabFrms, damit nicht alle Zellen abgehuehnert werden
1642 	if( bWrongPage )
1643 		pLayLeaf = 0;
1644 	else if( IsTabFrm() )
1645     {
1646 		SwCntntFrm* pTmpCnt = ((SwTabFrm*)this)->FindLastCntnt();
1647         pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : 0;
1648     }
1649 	else
1650 	{
1651 		pLayLeaf = GetNextLayoutLeaf();
1652 		if( IsColumnFrm() )
1653 		{
1654 			while( pLayLeaf && ((SwColumnFrm*)this)->IsAnLower( pLayLeaf ) )
1655 				pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1656 		}
1657 	}
1658 
1659 	SwLayoutFrm *pOldLayLeaf = 0;			//Damit bei neu erzeugten Seiten
1660 											//nicht wieder vom Anfang gesucht
1661 											//wird.
1662 
1663 	while( sal_True )
1664 	{
1665 		if( pLayLeaf )
1666 		{
1667 			// Ein Layoutblatt wurde gefunden, mal sehen, ob er mich aufnehmen kann,
1668 			// ob hier ein weiterer SectionFrm eingefuegt werden kann
1669 			// oder ob wir weitersuchen muessen.
1670 			SwPageFrm* pNxtPg = pLayLeaf->FindPageFrm();
1671 			if ( !bFtnPage && pNxtPg->IsFtnPage() )
1672 			{	//Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
1673 				pLayLeaf = 0;
1674 				continue;
1675 			}
1676 			// Einmal InBody, immer InBody, nicht in Tabellen hinein
1677 			// und nicht in fremde Bereiche hinein
1678 			if ( (bBody && !pLayLeaf->IsInDocBody()) ||
1679 				 (IsInFtn() != pLayLeaf->IsInFtn() ) ||
1680 				 pLayLeaf->IsInTab() ||
1681 				 ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
1682 				   || pSect->GetFollow() != pLayLeaf->FindSctFrm() ) ) )
1683 			{
1684 				//Er will mich nicht; neuer Versuch, neues Glueck
1685 				pOldLayLeaf = pLayLeaf;
1686 				pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1687 				continue;
1688 			}
1689 			if( WrongPageDesc( pNxtPg ) )
1690 			{
1691 				if( bWrongPage )
1692 					break; // there's a column between me and my right page
1693 				pLayLeaf = 0;
1694 				bWrongPage = sal_True;
1695 				pOldLayLeaf = 0;
1696 				continue;
1697 			}
1698 		}
1699 		//Es gibt keinen passenden weiteren LayoutFrm, also muss eine
1700 		//neue Seite her, allerdings nuetzen uns innerhalb eines Rahmens
1701 		//neue Seiten nichts.
1702 		else if( !pSect->IsInFly() &&
1703 			( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
1704 		{
1705 			InsertPage(pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
1706 					   sal_False );
1707 			//und nochmal das ganze
1708 			pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1709 			continue;
1710 		}
1711 		break;
1712 	}
1713 
1714 	if( pLayLeaf )
1715 	{
1716 		// Das passende Layoutblatt haben wir gefunden, wenn es dort bereits einen
1717 		// Follow unseres Bereichs gibt, nehmen wir dessen erstes Layoutblatt,
1718 		// andernfalls wird es Zeit, einen Bereichsfollow zu erzeugen
1719 		SwSectionFrm* pNew;
1720 
1721 		//Dies kann entfallen, wenn bei existierenden Follows bereits abgekuerzt wurde
1722 		SwFrm* pFirst = pLayLeaf->Lower();
1723 		// Auch hier muessen zum Loeschen angemeldete SectionFrms ignoriert werden
1724 		while( pFirst && pFirst->IsSctFrm() && !((SwSectionFrm*)pFirst)->GetSection() )
1725 			pFirst = pFirst->GetNext();
1726 		if( pFirst && pFirst->IsSctFrm() &&	pSect->GetFollow() == pFirst )
1727 			pNew = pSect->GetFollow();
1728 		else if( MAKEPAGE_NOSECTION == eMakePage )
1729 			return pLayLeaf;
1730 		else
1731 		{
1732             pNew = new SwSectionFrm( *pSect, sal_False );
1733 			pNew->InsertBefore( pLayLeaf, pLayLeaf->Lower() );
1734             pNew->Init();
1735             SWRECTFN( pNew )
1736             (pNew->*fnRect->fnMakePos)( pLayLeaf, NULL, sal_True );
1737 
1738 			// Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser
1739 			// umgehaengt werden hinter den neuen Follow der Bereichsframes.
1740 			SwFrm* pTmp = pSect->GetNext();
1741 			if( pTmp && pTmp != pSect->GetFollow() )
1742 			{
1743 				SwFlowFrm* pNxt;
1744 				SwCntntFrm* pNxtCntnt = NULL;
1745 				if( pTmp->IsCntntFrm() )
1746 				{
1747 					pNxt = (SwCntntFrm*)pTmp;
1748 					pNxtCntnt = (SwCntntFrm*)pTmp;
1749 				}
1750 				else
1751 				{
1752 					pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
1753 					if( pTmp->IsSctFrm() )
1754 						pNxt = (SwSectionFrm*)pTmp;
1755 					else
1756 					{
1757 						ASSERT( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
1758 						pNxt = (SwTabFrm*)pTmp;
1759 					}
1760 					while( !pNxtCntnt && 0 != ( pTmp = pTmp->GetNext() ) )
1761 					{
1762 						if( pTmp->IsCntntFrm() )
1763 							pNxtCntnt = (SwCntntFrm*)pTmp;
1764 						else
1765 							pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
1766 					}
1767 				}
1768 				if( pNxtCntnt )
1769 				{
1770 					SwFtnBossFrm* pOldBoss = pSect->FindFtnBossFrm( sal_True );
1771 					if( pOldBoss == pNxtCntnt->FindFtnBossFrm( sal_True ) )
1772 					{
1773 						SwSaveFtnHeight aHeight( pOldBoss,
1774 							pOldBoss->Frm().Top() + pOldBoss->Frm().Height() );
1775 						pSect->GetUpper()->MoveLowerFtns( pNxtCntnt, pOldBoss,
1776 									pLayLeaf->FindFtnBossFrm( sal_True ), sal_False );
1777 					}
1778 				}
1779 				((SwFlowFrm*)pNxt)->MoveSubTree( pLayLeaf, pNew->GetNext() );
1780 			}
1781 			if( pNew->GetFollow() )
1782 				pNew->SimpleFormat();
1783 		}
1784 		// Das gesuchte Layoutblatt ist jetzt das erste des ermittelten SctFrms:
1785 		pLayLeaf = FIRSTLEAF( pNew );
1786 	}
1787 	return pLayLeaf;
1788 }
1789 
1790 /*************************************************************************
1791 |*
1792 |*	SwFrm::GetPrevSctLeaf()
1793 |*
1794 |*	Beschreibung		Liefert das vorhergehende LayoutBlatt in das der
1795 |* 		Frame gemoved werden kann.
1796 |*	Ersterstellung		AMA 07. Jan. 98
1797 |*	Letzte Aenderung	AMA 07. Jan. 98
1798 |*
1799 |*************************************************************************/
1800 
1801 
1802 SwLayoutFrm *SwFrm::GetPrevSctLeaf( MakePageType )
1803 {
1804 	PROTOCOL_ENTER( this, PROT_LEAF, ACT_PREV_SECT, GetUpper()->FindSctFrm() )
1805 
1806 	SwLayoutFrm* pCol;
1807 	// ColumnFrm beinhalten jetzt stets einen BodyFrm
1808 	if( IsColBodyFrm() )
1809 		pCol = GetUpper();
1810 	else if( GetUpper()->IsColBodyFrm() )
1811 		pCol = GetUpper()->GetUpper();
1812 	else
1813 		pCol = NULL;
1814 	sal_Bool bJump = sal_False;
1815 	if( pCol )
1816 	{
1817 		if( pCol->GetPrev() )
1818 		{
1819 			do
1820 			{
1821 				pCol = (SwLayoutFrm*)pCol->GetPrev();
1822 				// Gibt es dort Inhalt?
1823 				if( ((SwLayoutFrm*)pCol->Lower())->Lower() )
1824 				{
1825 					if( bJump )		// Haben wir eine leere Spalte uebersprungen?
1826 						SwFlowFrm::SetMoveBwdJump( sal_True );
1827 					return (SwLayoutFrm*)pCol->Lower();  // Der Spaltenbody
1828 				}
1829 				bJump = sal_True;
1830 			} while( pCol->GetPrev() );
1831 
1832 			// Hier landen wir, wenn alle Spalten leer sind,
1833 			// pCol ist jetzt die erste Spalte, wir brauchen aber den Body:
1834 			pCol = (SwLayoutFrm*)pCol->Lower();
1835 		}
1836 		else
1837 			pCol = NULL;
1838 	}
1839 
1840 	if( bJump )		// Haben wir eine leere Spalte uebersprungen?
1841 		SwFlowFrm::SetMoveBwdJump( sal_True );
1842 
1843 	// Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann
1844 	// nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette
1845 	// zuschlagen muessen, ebenso wenn der Bereich einen pPrev hat.
1846 	// Jetzt ziehen wir sogar eine leere Spalte in Betracht...
1847 	ASSERT( FindSctFrm(), "GetNextSctLeaf: Missing SectionFrm" );
1848 	if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() )
1849 		return pCol;
1850 
1851     // === IMPORTANT ===
1852     // Precondition, which needs to be hold, is that the <this> frame can be
1853     // inside a table, but then the found section frame <pSect> is also inside
1854     // this table.
1855     SwSectionFrm *pSect = FindSctFrm();
1856 
1857     // --> OD 2009-01-16 #i95698#
1858     // A table cell containing directly a section does not break - see lcl_FindSectionsInRow(..)
1859     // Thus, a table inside a section, which is inside another table can only
1860     // flow backward in the columns of its section.
1861     // Note: The table cell, which contains the section, can not have a master table cell.
1862     if ( IsTabFrm() && pSect->IsInTab() )
1863     {
1864         return pCol;
1865     }
1866     // <--
1867 
1868     {
1869         SwFrm *pPrv;
1870         if( 0 != ( pPrv = pSect->GetIndPrev() ) )
1871         {
1872             // Herumlungernde, halbtote SectionFrms sollen uns nicht beirren
1873             while( pPrv && pPrv->IsSctFrm() && !((SwSectionFrm*)pPrv)->GetSection() )
1874                 pPrv = pPrv->GetPrev();
1875             if( pPrv )
1876                 return pCol;
1877         }
1878     }
1879 
1880 	const sal_Bool bBody = IsInDocBody();
1881 	const sal_Bool bFly  = IsInFly();
1882 
1883 	SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
1884 	SwLayoutFrm *pPrevLeaf = 0;
1885 
1886 	while ( pLayLeaf )
1887     {
1888         //In Tabellen oder Bereiche geht's niemals hinein.
1889         if ( pLayLeaf->IsInTab() || pLayLeaf->IsInSct() )
1890         {
1891             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1892         }
1893 		else if ( bBody && pLayLeaf->IsInDocBody() )
1894 		{
1895             // If there is a pLayLeaf has a lower pLayLeaf is the frame we are looking for.
1896             // Exception: pLayLeaf->Lower() is a zombie section frame
1897             const SwFrm* pTmp = pLayLeaf->Lower();
1898             // OD 11.04.2003 #108824# - consider, that the zombie section frame
1899             // can have frame below it in the found layout leaf.
1900             // Thus, skipping zombie section frame, if possible.
1901             while ( pTmp && pTmp->IsSctFrm() &&
1902                     !( static_cast<const SwSectionFrm*>(pTmp)->GetSection() ) &&
1903                     pTmp->GetNext()
1904                   )
1905             {
1906                 pTmp = pTmp->GetNext();
1907             }
1908             if ( pTmp &&
1909                  ( !pTmp->IsSctFrm() ||
1910                    ( static_cast<const SwSectionFrm*>(pTmp)->GetSection() )
1911                  )
1912                )
1913             {
1914         	    break;
1915             }
1916 			pPrevLeaf = pLayLeaf;
1917 			pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1918 			if ( pLayLeaf )
1919 				SwFlowFrm::SetMoveBwdJump( sal_True );
1920 		}
1921 		else if ( bFly )
1922 			break;	//Cntnts in Flys sollte jedes Layout-Blatt recht sein. Warum?
1923 		else
1924 			pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1925 	}
1926 	if( !pLayLeaf )
1927 	{
1928 		if( !pPrevLeaf )
1929 			return pCol;
1930 		pLayLeaf = pPrevLeaf;
1931 	}
1932 
1933 	SwSectionFrm* pNew = NULL;
1934 	// Zunaechst einmal an das Ende des Layoutblatts gehen
1935 	SwFrm *pTmp = pLayLeaf->Lower();
1936 	if( pTmp )
1937 	{
1938 		while( pTmp->GetNext() )
1939 			pTmp = pTmp->GetNext();
1940 		if( pTmp->IsSctFrm() )
1941 		{
1942 			// Halbtote stoeren hier nur...
1943 			while( !((SwSectionFrm*)pTmp)->GetSection() && pTmp->GetPrev() &&
1944 					pTmp->GetPrev()->IsSctFrm() )
1945 				pTmp = pTmp->GetPrev();
1946 			if( ((SwSectionFrm*)pTmp)->GetFollow() == pSect )
1947 				pNew = (SwSectionFrm*)pTmp;
1948 		}
1949 	}
1950 	if( !pNew )
1951 	{
1952         pNew = new SwSectionFrm( *pSect, sal_True );
1953 		pNew->InsertBefore( pLayLeaf, NULL );
1954         pNew->Init();
1955         SWRECTFN( pNew )
1956         (pNew->*fnRect->fnMakePos)( pLayLeaf, pNew->GetPrev(), sal_True );
1957 
1958 		pLayLeaf = FIRSTLEAF( pNew );
1959 		if( !pNew->Lower() )    // einspaltige Bereiche formatieren
1960 		{
1961 			pNew->MakePos();
1962 			pLayLeaf->Format(); // damit die PrtArea fuers MoveBwd stimmt
1963 		}
1964 		else
1965 			pNew->SimpleFormat();
1966 	}
1967 	else
1968 	{
1969 		pLayLeaf = FIRSTLEAF( pNew );
1970 		if( pLayLeaf->IsColBodyFrm() )
1971         {
1972             // In existent section columns we're looking for the last not empty
1973             // column.
1974             SwLayoutFrm *pTmpLay = pLayLeaf;
1975 			while( pLayLeaf->GetUpper()->GetNext() )
1976             {
1977 				pLayLeaf = (SwLayoutFrm*)((SwLayoutFrm*)pLayLeaf->GetUpper()->GetNext())->Lower();
1978                 if( pLayLeaf->Lower() )
1979                     pTmpLay = pLayLeaf;
1980             }
1981             // If we skipped an empty column, we've to set the jump-flag
1982             if( pLayLeaf != pTmpLay )
1983             {
1984                 pLayLeaf = pTmpLay;
1985                 SwFlowFrm::SetMoveBwdJump( sal_True );
1986             }
1987 		}
1988 	}
1989 	return pLayLeaf;
1990 }
1991 
1992 SwTwips lcl_DeadLine( const SwFrm* pFrm )
1993 {
1994 	const SwLayoutFrm* pUp = pFrm->GetUpper();
1995 	while( pUp && pUp->IsInSct() )
1996 	{
1997 		if( pUp->IsSctFrm() )
1998 			pUp = pUp->GetUpper();
1999 		// Spalten jetzt mit BodyFrm
2000 		else if( pUp->IsColBodyFrm() && pUp->GetUpper()->GetUpper()->IsSctFrm() )
2001 			pUp = pUp->GetUpper()->GetUpper();
2002 		else
2003 			break;
2004 	}
2005     SWRECTFN( pFrm )
2006     return pUp ? (pUp->*fnRect->fnGetPrtBottom)() :
2007                  (pFrm->Frm().*fnRect->fnGetBottom)();
2008 }
2009 
2010 // SwSectionFrm::Growable(..) prueft, ob der SectionFrm noch wachsen kann,
2011 // ggf. muss die Umgebung gefragt werden
2012 
2013 sal_Bool SwSectionFrm::Growable() const
2014 {
2015     SWRECTFN( this )
2016     if( (*fnRect->fnYDiff)( lcl_DeadLine( this ),
2017         (Frm().*fnRect->fnGetBottom)() ) > 0 )
2018 		return sal_True;
2019 
2020     return ( GetUpper() && ((SwFrm*)GetUpper())->Grow( LONG_MAX, sal_True ) );
2021 }
2022 
2023 /*************************************************************************
2024 |*
2025 |*	SwSectionFrm::_Grow(), _Shrink()
2026 |*
2027 |*	Ersterstellung		AMA 14. Jan. 98
2028 |*	Letzte Aenderung	AMA 14. Jan. 98
2029 |*
2030 |*************************************************************************/
2031 
2032 SwTwips SwSectionFrm::_Grow( SwTwips nDist, sal_Bool bTst )
2033 {
2034     if ( !IsColLocked() && !HasFixSize() )
2035 	{
2036         SWRECTFN( this )
2037         long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2038         if( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
2039             nDist = LONG_MAX - nFrmHeight;
2040 
2041 		if ( nDist <= 0L )
2042 			return 0L;
2043 
2044         sal_Bool bInCalcCntnt = GetUpper() && IsInFly() && FindFlyFrm()->IsLocked();
2045         // OD 2004-03-15 #116561# - allow grow in online layout
2046         sal_Bool bGrow = !Lower() || !Lower()->IsColumnFrm() || !Lower()->GetNext() ||
2047              GetSection()->GetFmt()->GetBalancedColumns().GetValue();
2048         if( !bGrow )
2049         {
2050              const ViewShell *pSh = getRootFrm()->GetCurrShell();
2051              bGrow = pSh && pSh->GetViewOptions()->getBrowseMode();
2052         }
2053         if( bGrow )
2054 		{
2055             SwTwips nGrow;
2056             if( IsInFtn() )
2057                 nGrow = 0;
2058             else
2059             {
2060                 nGrow = lcl_DeadLine( this );
2061                 nGrow = (*fnRect->fnYDiff)( nGrow,
2062                                            (Frm().*fnRect->fnGetBottom)() );
2063             }
2064 			SwTwips nSpace = nGrow;
2065             if( !bInCalcCntnt && nGrow < nDist && GetUpper() )
2066                 nGrow += GetUpper()->Grow( LONG_MAX, sal_True );
2067 
2068 			if( nGrow > nDist )
2069 				nGrow = nDist;
2070 			if( nGrow <= 0 )
2071 			{
2072 				nGrow = 0;
2073 				if( nDist && !bTst )
2074 				{
2075 					if( bInCalcCntnt )
2076 						_InvalidateSize();
2077 					else
2078 						InvalidateSize();
2079 				}
2080 			}
2081 			else if( !bTst )
2082 			{
2083 				if( bInCalcCntnt )
2084 					_InvalidateSize();
2085 				else if( nSpace < nGrow &&  nDist != nSpace + GetUpper()->
2086                          Grow( nGrow - nSpace, sal_False ) )
2087 					InvalidateSize();
2088 				else
2089 				{
2090 					const SvxGraphicPosition ePos =
2091 						GetAttrSet()->GetBackground().GetGraphicPos();
2092 					if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2093 					{
2094 						SetCompletePaint();
2095 						InvalidatePage();
2096 					}
2097                     if( GetUpper() && GetUpper()->IsHeaderFrm() )
2098                         GetUpper()->InvalidateSize();
2099 				}
2100                 (Frm().*fnRect->fnAddBottom)( nGrow );
2101                 long nPrtHeight = (Prt().*fnRect->fnGetHeight)() + nGrow;
2102                 (Prt().*fnRect->fnSetHeight)( nPrtHeight );
2103 
2104                 if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
2105 				{
2106 					SwFrm* pTmp = Lower();
2107 					do
2108 					{
2109 						pTmp->_InvalidateSize();
2110 						pTmp = pTmp->GetNext();
2111 					} while ( pTmp );
2112 					_InvalidateSize();
2113 				}
2114 				if( GetNext() )
2115 				{
2116 					SwFrm *pFrm = GetNext();
2117 					while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
2118 						pFrm = pFrm->GetNext();
2119 					if( pFrm )
2120 					{
2121 						if( bInCalcCntnt )
2122 							pFrm->_InvalidatePos();
2123 						else
2124 							pFrm->InvalidatePos();
2125 					}
2126 				}
2127                 // --> OD 2004-07-05 #i28701# - Due to the new object positioning
2128                 // the frame on the next page/column can flow backward (e.g. it
2129                 // was moved forward due to the positioning of its objects ).
2130                 // Thus, invalivate this next frame, if document compatibility
2131                 // option 'Consider wrapping style influence on object positioning' is ON.
2132                 else if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2133                 {
2134                     InvalidateNextPos();
2135                 }
2136                 // <--
2137 			}
2138 			return nGrow;
2139 		}
2140 		if ( !bTst )
2141 		{
2142 			if( bInCalcCntnt )
2143 				_InvalidateSize();
2144 			else
2145 				InvalidateSize();
2146 		}
2147 	}
2148 	return 0L;
2149 }
2150 
2151 SwTwips SwSectionFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
2152 {
2153     if ( Lower() && !IsColLocked() && !HasFixSize() )
2154 	{
2155 		if( ToMaximize( sal_False ) )
2156 		{
2157 			if( !bTst )
2158 				InvalidateSize();
2159 		}
2160 		else
2161 		{
2162             SWRECTFN( this )
2163             long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2164             if ( nDist > nFrmHeight )
2165                 nDist = nFrmHeight;
2166 
2167 			if ( Lower()->IsColumnFrm() && Lower()->GetNext() && // FtnAtEnd
2168 				 !GetSection()->GetFmt()->GetBalancedColumns().GetValue() )
2169 			{	//Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
2170 				//das Wachstum (wg. des Ausgleichs).
2171 				if ( !bTst )
2172 					InvalidateSize();
2173 				return nDist;
2174 			}
2175 			else if( !bTst )
2176 			{
2177 				const SvxGraphicPosition ePos =
2178 					GetAttrSet()->GetBackground().GetGraphicPos();
2179 				if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2180 				{
2181 					SetCompletePaint();
2182 					InvalidatePage();
2183 				}
2184                 (Frm().*fnRect->fnAddBottom)( -nDist );
2185                 long nPrtHeight = (Prt().*fnRect->fnGetHeight)() - nDist;
2186                 (Prt().*fnRect->fnSetHeight)( nPrtHeight );
2187 
2188                 SwTwips nReal = 0;
2189                 // We do not allow a section frame to shrink the its upper
2190                 // footer frame. This is because in the calculation of a
2191                 // footer frame, the content of the section frame is _not_
2192                 // calculated. If there is a fly frame overlapping with the
2193                 // footer frame, the section frame is not affected by this
2194                 // during the calculation of the footer frame size.
2195                 // The footer frame does not grow in its FormatSize function
2196                 // but during the calculation of the content of the section
2197                 // frame. The section frame grows until some of its text is
2198                 // located on top of the fly frame. The next call of CalcCntnt
2199                 // tries to shrink the section and here it would also shrink
2200                 // the footer. This may not happen, because shrinking the footer
2201                 // would cause the top of the section frame to overlap with the
2202                 // fly frame again, this would result in a perfect loop.
2203                 if( GetUpper() && !GetUpper()->IsFooterFrm() )
2204                     nReal = GetUpper()->Shrink( nDist, bTst );
2205 
2206                 if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
2207 				{
2208 					SwFrm* pTmp = Lower();
2209 					do
2210 					{
2211 						pTmp->_InvalidateSize();
2212 						pTmp = pTmp->GetNext();
2213 					} while ( pTmp );
2214 				}
2215 				if( GetNext() )
2216 				{
2217 					SwFrm* pFrm = GetNext();
2218 					while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
2219 						pFrm = pFrm->GetNext();
2220 					if( pFrm )
2221 						pFrm->InvalidatePos();
2222 					else
2223 						SetRetouche();
2224 				}
2225 				else
2226 					SetRetouche();
2227 				return nDist;
2228 			}
2229 		}
2230 	}
2231 	return 0L;
2232 }
2233 
2234 /*************************************************************************
2235 |*
2236 |*	SwSectionFrm::MoveAllowed()
2237 |*
2238 |*	Ersterstellung		MA 08. Oct. 98
2239 |*	Letzte Aenderung	MA 08. Oct. 98
2240 |*
2241 |*	Wann sind Frms innerhalb eines SectionFrms moveable?
2242 |*  Wenn sie noch nicht in der letzten Spalte des SectionFrms sind,
2243 |* 	wenn es einen Follow gibt,
2244 |*  wenn der SectionFrm nicht mehr wachsen kann, wird es komplizierter,
2245 |*  dann kommt es darauf an, ob der SectionFrm ein naechstes Layoutblatt
2246 |*  finden kann. In (spaltigen/verketteten) Flys wird dies via GetNextLayout
2247 |* 	geprueft, in Tabellen und in Kopf/Fusszeilen gibt es keins, im DocBody
2248 |*  und auch im Fussnoten dagegen immer.
2249 |*
2250 |*  Benutzt wird diese Routine im TxtFormatter, um zu entscheiden, ob ein
2251 |* 	(Absatz-)Follow erzeugt werden darf oder ob der Absatz zusammenhalten muss.
2252 |*
2253 |*************************************************************************/
2254 
2255 sal_Bool SwSectionFrm::MoveAllowed( const SwFrm* pFrm) const
2256 {
2257 	// Gibt es einen Follow oder ist der Frame nicht in der letzten Spalte?
2258 	if( HasFollow() || ( pFrm->GetUpper()->IsColBodyFrm() &&
2259 		pFrm->GetUpper()->GetUpper()->GetNext() ) )
2260 		return sal_True;
2261 	if( pFrm->IsInFtn() )
2262 	{
2263 		if( IsInFtn() )
2264 		{
2265 			if( GetUpper()->IsInSct() )
2266 			{
2267 				if( Growable() )
2268 					return sal_False;
2269 				return GetUpper()->FindSctFrm()->MoveAllowed( this );
2270 			}
2271 			else
2272 				return sal_True;
2273 		}
2274 		// The content of footnote inside a columned sectionfrm is moveable
2275 		// except in the last column
2276 		const SwLayoutFrm *pLay = pFrm->FindFtnFrm()->GetUpper()->GetUpper();
2277 		if( pLay->IsColumnFrm() && pLay->GetNext() )
2278 		{
2279 			// The first paragraph in the first footnote in the first column
2280 			// in the sectionfrm at the top of the page is not moveable,
2281 			// if the columnbody is empty.
2282 			sal_Bool bRet = sal_False;
2283 			if( pLay->GetIndPrev() || pFrm->GetIndPrev() ||
2284 				pFrm->FindFtnFrm()->GetPrev() )
2285 				bRet = sal_True;
2286 			else
2287 			{
2288 				SwLayoutFrm* pBody = ((SwColumnFrm*)pLay)->FindBodyCont();
2289 				if( pBody && pBody->Lower() )
2290 					bRet = sal_True;
2291 			}
2292 			if( bRet && ( IsFtnAtEnd() || !Growable() ) )
2293 				return sal_True;
2294 		}
2295 	}
2296 	// Oder kann der Bereich noch wachsen?
2297 	if(	!IsColLocked() && Growable() )
2298 		return sal_False;
2299 	// Jetzt muss untersucht werden, ob es ein Layoutblatt gibt, in dem
2300 	// ein Bereichsfollow erzeugt werden kann.
2301 	if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) )
2302 		return sal_False; // In Tabellen/Kopf/Fusszeilen geht es nicht
2303 	if( IsInFly() ) // Bei spaltigen oder verketteten Rahmen
2304 		return 0 != ((SwFrm*)GetUpper())->GetNextLeaf( MAKEPAGE_NONE );
2305 	return sal_True;
2306 }
2307 
2308 /** Called for a frame inside a section with no direct previous frame (or only
2309     previous empty section frames) the previous frame of the outer section is
2310     returned, if the frame is the first flowing content of this section.
2311 
2312     Note: For a frame inside a table frame, which is inside a section frame,
2313           NULL is returned.
2314 */
2315 SwFrm* SwFrm::_GetIndPrev() const
2316 {
2317 	SwFrm *pRet = NULL;
2318     // --> OD 2007-09-04 #i79774#, #b659654#
2319     // Do not assert, if the frame has a direct previous frame, because it
2320     // could be an empty section frame. The caller has to assure, that the
2321     // frame has no direct previous frame or only empty section frames as
2322     // previous frames.
2323     ASSERT( /*!pPrev &&*/ IsInSct(), "Why?" );
2324     // <--
2325     const SwFrm* pSct = GetUpper();
2326 	if( !pSct )
2327 		return NULL;
2328 	if( pSct->IsSctFrm() )
2329 		pRet = pSct->GetIndPrev();
2330 	else if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
2331     {
2332         // Do not return the previous frame of the outer section, if in one
2333         // of the previous columns is content.
2334         const SwFrm* pCol = GetUpper()->GetUpper()->GetPrev();
2335 		while( pCol )
2336 		{
2337 			ASSERT( pCol->IsColumnFrm(), "GetIndPrev(): ColumnFrm expected" );
2338 			ASSERT( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
2339 					"GetIndPrev(): Where's the body?");
2340 			if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
2341 				return NULL;
2342 			pCol = pCol->GetPrev();
2343 		}
2344 		pRet = pSct->GetIndPrev();
2345 	}
2346 
2347     // skip empty section frames
2348 	while( pRet && pRet->IsSctFrm() && !((SwSectionFrm*)pRet)->GetSection() )
2349 		pRet = pRet->GetIndPrev();
2350 	return pRet;
2351 }
2352 
2353 SwFrm* SwFrm::_GetIndNext()
2354 {
2355 	ASSERT( !pNext && IsInSct(), "Why?" );
2356 	SwFrm* pSct = GetUpper();
2357 	if( !pSct )
2358 		return NULL;
2359 	if( pSct->IsSctFrm() )
2360 		return pSct->GetIndNext();
2361 	if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
2362 	{	// Wir duerfen nur den Nachfolger des SectionFrms zurueckliefern,
2363 		// wenn in keiner folgenden Spalte mehr Inhalt ist
2364 		SwFrm* pCol = GetUpper()->GetUpper()->GetNext();
2365 		while( pCol )
2366 		{
2367 			ASSERT( pCol->IsColumnFrm(), "GetIndNext(): ColumnFrm expected" );
2368 			ASSERT( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
2369 					"GetIndNext(): Where's the body?");
2370 			if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
2371 				return NULL;
2372 			pCol = pCol->GetNext();
2373 		}
2374 		return pSct->GetIndNext();
2375 	}
2376 	return NULL;
2377 }
2378 
2379 sal_Bool SwSectionFrm::IsDescendantFrom( const SwSectionFmt* pFmt ) const
2380 {
2381 	if( !pSection || !pFmt )
2382 		return sal_False;
2383 	const SwSectionFmt *pMyFmt = pSection->GetFmt();
2384 	while( pFmt != pMyFmt )
2385 	{
2386 		if( pMyFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
2387 			pMyFmt = (SwSectionFmt*)pMyFmt->GetRegisteredIn();
2388 		else
2389 			return sal_False;
2390 	}
2391 	return sal_True;
2392 }
2393 
2394 void SwSectionFrm::CalcFtnAtEndFlag()
2395 {
2396 	SwSectionFmt *pFmt = GetSection()->GetFmt();
2397 	sal_uInt16 nVal = pFmt->GetFtnAtTxtEnd( sal_False ).GetValue();
2398 	bFtnAtEnd = FTNEND_ATPGORDOCEND != nVal;
2399 	bOwnFtnNum = FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
2400 				 FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
2401 	while( !bFtnAtEnd && !bOwnFtnNum )
2402 	{
2403 		if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
2404 			pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
2405 		else
2406 			break;
2407 		nVal = pFmt->GetFtnAtTxtEnd( sal_False ).GetValue();
2408 		if( FTNEND_ATPGORDOCEND != nVal )
2409 		{
2410 			bFtnAtEnd = sal_True;
2411 			bOwnFtnNum = bOwnFtnNum ||FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
2412 						 FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
2413 		}
2414 	}
2415 }
2416 
2417 sal_Bool SwSectionFrm::IsEndnoteAtMyEnd() const
2418 {
2419 	return pSection->GetFmt()->GetEndAtTxtEnd( sal_False ).IsAtEnd();
2420 }
2421 
2422 void SwSectionFrm::CalcEndAtEndFlag()
2423 {
2424 	SwSectionFmt *pFmt = GetSection()->GetFmt();
2425 	bEndnAtEnd = pFmt->GetEndAtTxtEnd( sal_False ).IsAtEnd();
2426 	while( !bEndnAtEnd )
2427 	{
2428 		if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
2429 			pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
2430 		else
2431 			break;
2432 		bEndnAtEnd = pFmt->GetEndAtTxtEnd( sal_False ).IsAtEnd();
2433 	}
2434 }
2435 
2436 /*************************************************************************
2437 |*
2438 |*	SwSectionFrm::Modify()
2439 |*
2440 |*	Ersterstellung		MA 08. Oct. 98
2441 |*	Letzte Aenderung	MA 08. Oct. 98
2442 |*
2443 |*************************************************************************/
2444 
2445 void SwSectionFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
2446 {
2447 	sal_uInt8 nInvFlags = 0;
2448 
2449 	if( pNew && RES_ATTRSET_CHG == pNew->Which() )
2450 	{
2451 		SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
2452 		SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
2453 		SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
2454 		SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
2455 		while( sal_True )
2456 		{
2457 			_UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
2458 						 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
2459 						 &aOldSet, &aNewSet );
2460 			if( aNIter.IsAtEnd() )
2461 				break;
2462 			aNIter.NextItem();
2463 			aOIter.NextItem();
2464 		}
2465 		if ( aOldSet.Count() || aNewSet.Count() )
2466 			SwLayoutFrm::Modify( &aOldSet, &aNewSet );
2467 	}
2468 	else
2469 		_UpdateAttr( pOld, pNew, nInvFlags );
2470 
2471 	if ( nInvFlags != 0 )
2472 	{
2473 		if ( nInvFlags & 0x01 )
2474 			InvalidateSize();
2475 		if ( nInvFlags & 0x10 )
2476 			SetCompletePaint();
2477 	}
2478 }
2479 
2480 void SwSectionFrm::SwClientNotify( const SwModify& rMod, const SfxHint& rHint )
2481 {
2482     // --> OD #i117863#
2483     const SwSectionFrmMoveAndDeleteHint* pHint =
2484                     dynamic_cast<const SwSectionFrmMoveAndDeleteHint*>(&rHint);
2485     if ( pHint && pHint->GetId() == SFX_HINT_DYING && &rMod == GetRegisteredIn() )
2486     {
2487         SwSectionFrm::MoveCntntAndDelete( this, pHint->IsSaveCntnt() );
2488     }
2489     // <--
2490 }
2491 
2492 void SwSectionFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
2493 							sal_uInt8 &rInvFlags,
2494 							SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2495 {
2496 	sal_Bool bClear = sal_True;
2497 	const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2498 	switch( nWhich )
2499 	{   // Mehrspaltigkeit in Fussnoten unterdruecken...
2500 		case RES_FMT_CHG:
2501 		{
2502 			const SwFmtCol& rNewCol = GetFmt()->GetCol();
2503 			if( !IsInFtn() )
2504 			{
2505 				//Dummer Fall. Bei der Zuweisung einer Vorlage k?nnen wir uns
2506 				//nicht auf das alte Spaltenattribut verlassen. Da diese
2507 				//wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
2508 				//bleibt uns nur einen temporaeres Attribut zu basteln.
2509 				SwFmtCol aCol;
2510 				if ( Lower() && Lower()->IsColumnFrm() )
2511 				{
2512 					sal_uInt16 nCol = 0;
2513 					SwFrm *pTmp = Lower();
2514 					do
2515 					{	++nCol;
2516 						pTmp = pTmp->GetNext();
2517 					} while ( pTmp );
2518 					aCol.Init( nCol, 0, 1000 );
2519 				}
2520 				sal_Bool bChgFtn = IsFtnAtEnd();
2521 				sal_Bool bChgEndn = IsEndnAtEnd();
2522 				sal_Bool bChgMyEndn = IsEndnoteAtMyEnd();
2523 				CalcFtnAtEndFlag();
2524 				CalcEndAtEndFlag();
2525 				bChgFtn = ( bChgFtn != IsFtnAtEnd() ) ||
2526 						  ( bChgEndn != IsEndnAtEnd() ) ||
2527 						  ( bChgMyEndn != IsEndnoteAtMyEnd() );
2528 				ChgColumns( aCol, rNewCol, bChgFtn );
2529 				rInvFlags |= 0x10;
2530 			}
2531 			rInvFlags |= 0x01;
2532 			bClear = sal_False;
2533 		}
2534 			break;
2535 
2536 		case RES_COL:
2537 			if( !IsInFtn() )
2538 			{
2539 				ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
2540 				rInvFlags |= 0x11;
2541 			}
2542 			break;
2543 
2544 		case RES_FTN_AT_TXTEND:
2545 			if( !IsInFtn() )
2546 			{
2547 				sal_Bool bOld = IsFtnAtEnd();
2548 				CalcFtnAtEndFlag();
2549 				if( bOld != IsFtnAtEnd() )
2550 				{
2551 					const SwFmtCol& rNewCol = GetFmt()->GetCol();
2552 					ChgColumns( rNewCol, rNewCol, sal_True );
2553 					rInvFlags |= 0x01;
2554 				}
2555 			}
2556 			break;
2557 
2558 		case RES_END_AT_TXTEND:
2559 			if( !IsInFtn() )
2560 			{
2561 				sal_Bool bOld = IsEndnAtEnd();
2562 				sal_Bool bMyOld = IsEndnoteAtMyEnd();
2563 				CalcEndAtEndFlag();
2564 				if( bOld != IsEndnAtEnd() || bMyOld != IsEndnoteAtMyEnd())
2565 				{
2566 					const SwFmtCol& rNewCol = GetFmt()->GetCol();
2567 					ChgColumns( rNewCol, rNewCol, sal_True );
2568 					rInvFlags |= 0x01;
2569 				}
2570 			}
2571 			break;
2572 		case RES_COLUMNBALANCE:
2573 			rInvFlags |= 0x01;
2574 			break;
2575 
2576         case RES_FRAMEDIR :
2577             SetDerivedR2L( sal_False );
2578             CheckDirChange();
2579             break;
2580 
2581 		case RES_PROTECT:
2582 			{
2583 				ViewShell *pSh = getRootFrm()->GetCurrShell();
2584 				if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
2585 					pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
2586 			}
2587 			break;
2588 
2589 		default:
2590 			bClear = sal_False;
2591 	}
2592 	if ( bClear )
2593 	{
2594 		if ( pOldSet || pNewSet )
2595 		{
2596 			if ( pOldSet )
2597 				pOldSet->ClearItem( nWhich );
2598 			if ( pNewSet )
2599 				pNewSet->ClearItem( nWhich );
2600 		}
2601 		else
2602 			SwLayoutFrm::Modify( pOld, pNew );
2603 	}
2604 }
2605 
2606 /*-----------------09.06.99 14:58-------------------
2607  * SwSectionFrm::ToMaximize(..): A follow or a ftncontainer at the end of the
2608  * page causes a maximal Size of the sectionframe.
2609  * --------------------------------------------------*/
2610 
2611 sal_Bool SwSectionFrm::ToMaximize( sal_Bool bCheckFollow ) const
2612 {
2613 	if( HasFollow() )
2614 	{
2615 		if( !bCheckFollow ) // Don't check superfluous follows
2616 			return sal_True;
2617 		const SwSectionFrm* pFoll = GetFollow();
2618 		while( pFoll && pFoll->IsSuperfluous() )
2619 			pFoll = pFoll->GetFollow();
2620 		if( pFoll )
2621 			return sal_True;
2622 	}
2623 	if( IsFtnAtEnd() )
2624 		return sal_False;
2625 	const SwFtnContFrm* pCont = ContainsFtnCont();
2626 	if( !IsEndnAtEnd() )
2627 		return 0 != pCont;
2628 	sal_Bool bRet = sal_False;
2629 	while( pCont && !bRet )
2630 	{
2631 		if( pCont->FindFootNote() )
2632 			bRet = sal_True;
2633 		else
2634 			pCont = ContainsFtnCont( pCont );
2635 	}
2636 	return bRet;
2637 }
2638 
2639 /*-----------------09.06.99 15:07-------------------
2640  * sal_Bool SwSectionFrm::ContainsFtnCont()
2641  * checks every Column for FtnContFrms.
2642  * --------------------------------------------------*/
2643 
2644 SwFtnContFrm* SwSectionFrm::ContainsFtnCont( const SwFtnContFrm* pCont ) const
2645 {
2646 	SwFtnContFrm* pRet = NULL;
2647 	const SwLayoutFrm* pLay;
2648 	if( pCont )
2649 	{
2650 		pLay = pCont->FindFtnBossFrm( 0 );
2651 		ASSERT( IsAnLower( pLay ), "ConatainsFtnCont: Wrong FtnContainer" );
2652 		pLay = (SwLayoutFrm*)pLay->GetNext();
2653 	}
2654 	else if( Lower() && Lower()->IsColumnFrm() )
2655 		pLay = (SwLayoutFrm*)Lower();
2656 	else
2657 		pLay = NULL;
2658 	while ( !pRet && pLay )
2659 	{
2660 		if( pLay->Lower() && pLay->Lower()->GetNext() )
2661 		{
2662 			ASSERT( pLay->Lower()->GetNext()->IsFtnContFrm(),
2663 					"ToMaximize: Unexspected Frame" );
2664 			pRet = (SwFtnContFrm*)pLay->Lower()->GetNext();
2665 		}
2666 		ASSERT( !pLay->GetNext() || pLay->GetNext()->IsLayoutFrm(),
2667 				"ToMaximize: ColFrm exspected" );
2668 		pLay = (SwLayoutFrm*)pLay->GetNext();
2669 	}
2670 	return pRet;
2671 }
2672 
2673 void SwSectionFrm::InvalidateFtnPos()
2674 {
2675 	SwFtnContFrm* pCont = ContainsFtnCont( NULL );
2676 	if( pCont )
2677 	{
2678 		SwFrm *pTmp = pCont->ContainsCntnt();
2679 		if( pTmp )
2680 			pTmp->_InvalidatePos();
2681 	}
2682 }
2683 
2684 /*-----------------18.03.99 10:37-------------------
2685  * SwSectionFrm::Undersize() liefert den Betrag, um den der Bereich gern
2686  * groesser waere, wenn in ihm Undersized TxtFrms liegen, ansonsten Null.
2687  * Das Undersized-Flag wird ggf. korrigiert.
2688  * --------------------------------------------------*/
2689 
2690 long SwSectionFrm::Undersize( sal_Bool bOverSize )
2691 {
2692 	bUndersized = sal_False;
2693     SWRECTFN( this )
2694     long nRet = InnerHeight() - (Prt().*fnRect->fnGetHeight)();
2695 	if( nRet > 0 )
2696 		bUndersized = sal_True;
2697 	else if( !bOverSize )
2698 		nRet = 0;
2699 	return nRet;
2700 }
2701 
2702 /// OD 01.04.2003 #108446# - determine next frame for footnote/endnote formatting
2703 /// before format of current one, because current one can move backward.
2704 /// After moving backward to a previous page method <FindNext()> will return
2705 /// the text frame presenting the first page footnote, if it exists. Thus, the
2706 /// rest of the footnote/endnote container would not be formatted.
2707 void SwSectionFrm::CalcFtnCntnt()
2708 {
2709 	SwFtnContFrm* pCont = ContainsFtnCont();
2710 	if( pCont )
2711 	{
2712 		SwFrm* pFrm = pCont->ContainsAny();
2713 		if( pFrm )
2714 			pCont->Calc();
2715 		while( pFrm && IsAnLower( pFrm ) )
2716 		{
2717 			SwFtnFrm* pFtn = pFrm->FindFtnFrm();
2718 			if( pFtn )
2719 				pFtn->Calc();
2720             // OD 01.04.2003 #108446# - determine next frame before format current frame.
2721             SwFrm* pNextFrm = 0;
2722             {
2723                 if( pFrm->IsSctFrm() )
2724                 {
2725                     pNextFrm = static_cast<SwSectionFrm*>(pFrm)->ContainsAny();
2726                 }
2727                 if( !pNextFrm )
2728                 {
2729                     pNextFrm = pFrm->FindNext();
2730                 }
2731             }
2732 			pFrm->Calc();
2733             pFrm = pNextFrm;
2734 		}
2735 	}
2736 }
2737 
2738 /* -----------------09.02.99 14:26-------------------
2739  * Wenn ein SectionFrm leerlaeuft, z.B. weil sein Inhalt die Seite/Spalte wechselt,
2740  * so wird er nicht sofort zerstoert (es koennte noch jemand auf dem Stack einen Pointer
2741  * auf ihn halten), sondern er traegt sich in eine Liste am RootFrm ein, die spaeter
2742  * abgearbeitet wird (in LayAction::Action u.a.). Seine Groesse wird auf Null gesetzt und
2743  * sein Zeiger auf seine Section ebenfalls. Solche zum Loeschen vorgesehene SectionFrms
2744  * muessen vom Layout/beim Formatieren ignoriert werden.
2745  *
2746  * Mit InsertEmptySct nimmt der RootFrm einen SectionFrm in die Liste auf,
2747  * mit RemoveFromList kann ein SectionFrm wieder aus der Liste entfernt werden (Dtor),
2748  * mit DeleteEmptySct wird die Liste abgearbeitet und die SectionFrms zerstoert
2749  * --------------------------------------------------*/
2750 
2751 void SwRootFrm::InsertEmptySct( SwSectionFrm* pDel )
2752 {
2753 	if( !pDestroy )
2754 		pDestroy = new SwDestroyList;
2755 	sal_uInt16 nPos;
2756 	if( !pDestroy->Seek_Entry( pDel, &nPos ) )
2757 		pDestroy->Insert( pDel );
2758 }
2759 
2760 void SwRootFrm::_DeleteEmptySct()
2761 {
2762 	ASSERT( pDestroy, "Keine Liste, keine Kekse" );
2763 	while( pDestroy->Count() )
2764 	{
2765 		SwSectionFrm* pSect = (*pDestroy)[0];
2766 		pDestroy->Remove( sal_uInt16(0) );
2767 		ASSERT( !pSect->IsColLocked() && !pSect->IsJoinLocked(),
2768 				"DeleteEmptySct: Locked SectionFrm" );
2769 		if( !pSect->Frm().HasArea() && !pSect->ContainsCntnt() )
2770 		{
2771 			SwLayoutFrm* pUp = pSect->GetUpper();
2772 			pSect->Remove();
2773 			delete pSect;
2774 			if( pUp && !pUp->Lower() )
2775 			{
2776 				if( pUp->IsPageBodyFrm() )
2777 					pUp->getRootFrm()->SetSuperfluous();
2778 				else if( pUp->IsFtnFrm() && !pUp->IsColLocked() &&
2779 					pUp->GetUpper() )
2780 				{
2781 					pUp->Cut();
2782 					delete pUp;
2783 				}
2784 			}
2785 		}
2786 		else {
2787 			ASSERT( pSect->GetSection(), "DeleteEmptySct: Halbtoter SectionFrm?!" );
2788         }
2789 	}
2790 }
2791 
2792 void SwRootFrm::_RemoveFromList( SwSectionFrm* pSct )
2793 {
2794 	ASSERT( pDestroy, "Where's my list?" );
2795 	sal_uInt16 nPos;
2796 	if( pDestroy->Seek_Entry( pSct, &nPos ) )
2797 		pDestroy->Remove( nPos );
2798 }
2799 
2800 #ifdef DBG_UTIL
2801 
2802 sal_Bool SwRootFrm::IsInDelList( SwSectionFrm* pSct ) const
2803 {
2804 	sal_uInt16 nPos;
2805 	return ( pDestroy && pDestroy->Seek_Entry( pSct, &nPos ) );
2806 }
2807 
2808 #endif
2809 
2810 bool SwSectionFrm::IsBalancedSection() const
2811 {
2812     bool bRet = false;
2813     if ( GetSection() && Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
2814     {
2815         bRet = !GetSection()->GetFmt()->GetBalancedColumns().GetValue();
2816     }
2817     return bRet;
2818 }
2819 
2820