xref: /aoo41x/main/sw/source/core/layout/flowfrm.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 #include "pam.hxx"
31 #include "swtable.hxx"
32 #include "frame.hxx"
33 #include "rootfrm.hxx"
34 #include "pagefrm.hxx"
35 #include "flyfrm.hxx"
36 #include "viewsh.hxx"
37 #include "doc.hxx"
38 #include "viewimp.hxx"
39 #include "viewopt.hxx"
40 #include "dflyobj.hxx"
41 #include "frmtool.hxx"
42 #include "dcontact.hxx"
43 #include <editeng/brkitem.hxx>
44 #include <editeng/keepitem.hxx>
45 #include <fmtsrnd.hxx>
46 #include <fmtanchr.hxx>
47 #include <fmtpdsc.hxx>
48 #include <editeng/ulspitem.hxx>
49 #include <tgrditem.hxx>
50 #include <txtftn.hxx>
51 #include <fmtftn.hxx>
52 #include <editeng/pgrditem.hxx>
53 #include <paratr.hxx>
54 #include "ftnfrm.hxx"
55 #include "txtfrm.hxx"
56 #include "tabfrm.hxx"
57 #include "pagedesc.hxx"
58 #include "layact.hxx"
59 #include "fmtornt.hxx"
60 #include "flyfrms.hxx"
61 #include "sectfrm.hxx"
62 #include "section.hxx"
63 #include "dbg_lay.hxx"
64 #include "lineinfo.hxx"
65 #include <fmtclbl.hxx>
66 #include <sortedobjs.hxx>
67 #include <layouter.hxx>
68 #include <fmtfollowtextflow.hxx>
69 #include <switerator.hxx>
70 
71 sal_Bool SwFlowFrm::bMoveBwdJump = sal_False;
72 
73 
74 /*************************************************************************
75 |*
76 |*	SwFlowFrm::SwFlowFrm()
77 |*
78 |*	Ersterstellung		MA 26. Apr. 95
79 |*	Letzte Aenderung	MA 26. Apr. 95
80 |*
81 |*************************************************************************/
82 
83 
84 SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
85 	rThis( rFrm ),
86 	pFollow( 0 )
87 {
88     bLockJoin = bIsFollow = bCntntLock = bOwnFtnNum =
89         bFtnLock = bFlyLock = sal_False;
90 }
91 
92 
93 /*************************************************************************
94 |*
95 |*  SwFlowFrm::IsFollowLocked()
96 |*     return sal_True if any follow has the JoinLocked flag
97 |*
98 |*************************************************************************/
99 
100 sal_Bool SwFlowFrm::HasLockedFollow() const
101 {
102     const SwFlowFrm* pFrm = GetFollow();
103     while( pFrm )
104     {
105         if( pFrm->IsJoinLocked() )
106             return sal_True;
107         pFrm = pFrm->GetFollow();
108     }
109     return sal_False;
110 }
111 
112 /*************************************************************************
113 |*
114 |*	SwFlowFrm::IsKeepFwdMoveAllowed()
115 |*
116 |*	Ersterstellung		MA 20. Jul. 94
117 |*	Letzte Aenderung	MA 16. May. 95
118 |*
119 |*************************************************************************/
120 
121 
122 sal_Bool SwFlowFrm::IsKeepFwdMoveAllowed()
123 {
124 	//Wenn der Vorgaenger das KeepAttribut traegt und auch dessen
125 	//Vorgaenger usw. bis zum ersten der Kette und fuer diesen das
126 	//IsFwdMoveAllowed ein sal_False liefert, so ist das Moven eben nicht erlaubt.
127 	SwFrm *pFrm = &rThis;
128 	if ( !pFrm->IsInFtn() )
129 		do
130 		{	if ( pFrm->GetAttrSet()->GetKeep().GetValue() )
131 				pFrm = pFrm->GetIndPrev();
132 			else
133 				return sal_True;
134 		} while ( pFrm );
135 
136 				  //Siehe IsFwdMoveAllowed()
137     sal_Bool bRet = sal_False;
138     if ( pFrm && pFrm->GetIndPrev() )
139         bRet = sal_True;
140 	return bRet;
141 }
142 
143 /*************************************************************************
144 |*
145 |*	  SwFlowFrm::CheckKeep()
146 |*
147 |*	  Beschreibung
148 |*	  Ersterstellung	MA 20. Jun. 95
149 |*	  Letzte Aenderung	MA 09. Apr. 97
150 |*
151 |*************************************************************************/
152 
153 
154 void SwFlowFrm::CheckKeep()
155 {
156 	//Den 'letzten' Vorgaenger mit KeepAttribut anstossen, denn
157 	//die ganze Truppe koennte zuruckrutschen.
158 	SwFrm *pPre = rThis.GetIndPrev();
159 	if( pPre->IsSctFrm() )
160 	{
161 		SwFrm *pLast = ((SwSectionFrm*)pPre)->FindLastCntnt();
162 		if( pLast && pLast->FindSctFrm() == pPre )
163 			pPre = pLast;
164 		else
165 			return;
166 	}
167 	SwFrm* pTmp;
168 	sal_Bool bKeep;
169 	while ( sal_True == (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) &&
170 			0 != ( pTmp = pPre->GetIndPrev() ) )
171 	{
172 		if( pTmp->IsSctFrm() )
173 		{
174 			SwFrm *pLast = ((SwSectionFrm*)pTmp)->FindLastCntnt();
175 			if( pLast && pLast->FindSctFrm() == pTmp )
176 				pTmp = pLast;
177 			else
178 				break;
179 		}
180 		pPre = pTmp;
181 	}
182 	if ( bKeep )
183 		pPre->InvalidatePos();
184 }
185 
186 /*************************************************************************
187 |*
188 |*	SwFlowFrm::IsKeep()
189 |*
190 |*	Ersterstellung		MA 09. Apr. 97
191 |*	Letzte Aenderung	MA 09. Apr. 97
192 |*
193 |*************************************************************************/
194 
195 sal_Bool SwFlowFrm::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKeep ) const
196 {
197     // 1. The keep attribute is ignored inside footnotes
198     // 2. For compatibility reasons, the keep attribute is
199     //    ignored for frames inside table cells
200     // 3. If bBreakCheck is set to true, this function only checks
201     //    if there are any break after attributes set at rAttrs
202     //    or break before attributes set for the next content (or next table)
203     sal_Bool bKeep = bCheckIfLastRowShouldKeep ||
204                  (  !rThis.IsInFtn() &&
205                     ( !rThis.IsInTab() || rThis.IsTabFrm() ) &&
206                     rAttrs.GetKeep().GetValue() );
207 
208     ASSERT( !bCheckIfLastRowShouldKeep || rThis.IsTabFrm(),
209             "IsKeep with bCheckIfLastRowShouldKeep should only be used for tabfrms" )
210 
211     // Ignore keep attribute if there are break situations:
212 	if ( bKeep )
213 	{
214         switch ( rAttrs.GetBreak().GetBreak() )
215 		{
216 			case SVX_BREAK_COLUMN_AFTER:
217 			case SVX_BREAK_COLUMN_BOTH:
218 			case SVX_BREAK_PAGE_AFTER:
219 			case SVX_BREAK_PAGE_BOTH:
220             {
221 				bKeep = sal_False;
222             }
223             default: break;
224 		}
225 		if ( bKeep )
226 		{
227 			SwFrm *pNxt;
228 			if( 0 != (pNxt = rThis.FindNextCnt()) &&
229 				(!pFollow || pNxt != pFollow->GetFrm()))
230 			{
231                 // --> FME 2006-05-15 #135914#
232                 // The last row of a table only keeps with the next content
233                 // it they are in the same section:
234                 if ( bCheckIfLastRowShouldKeep )
235                 {
236                     const SwSection* pThisSection = 0;
237                     const SwSection* pNextSection = 0;
238                     const SwSectionFrm* pThisSectionFrm = rThis.FindSctFrm();
239                     const SwSectionFrm* pNextSectionFrm = pNxt->FindSctFrm();
240 
241                     if ( pThisSectionFrm )
242                         pThisSection = pThisSectionFrm->GetSection();
243 
244                     if ( pNextSectionFrm )
245                         pNextSection = pNextSectionFrm->GetSection();
246 
247                     if ( pThisSection != pNextSection )
248                         bKeep = sal_False;
249                 }
250                 // <--
251 
252                 if ( bKeep )
253                 {
254                     const SwAttrSet* pSet = NULL;
255 
256                     if ( pNxt->IsInTab() )
257                     {
258                         SwTabFrm* pTab = pNxt->FindTabFrm();
259                         if ( ! rThis.IsInTab() || rThis.FindTabFrm() != pTab )
260                             pSet = &pTab->GetFmt()->GetAttrSet();
261                     }
262 
263                     if ( ! pSet )
264                         pSet = pNxt->GetAttrSet();
265 
266                     ASSERT( pSet, "No AttrSet to check keep attribute" )
267 
268                     if ( pSet->GetPageDesc().GetPageDesc() )
269                         bKeep = sal_False;
270                     else switch ( pSet->GetBreak().GetBreak() )
271                     {
272                         case SVX_BREAK_COLUMN_BEFORE:
273                         case SVX_BREAK_COLUMN_BOTH:
274                         case SVX_BREAK_PAGE_BEFORE:
275                         case SVX_BREAK_PAGE_BOTH:
276                             bKeep = sal_False;
277                         default: break;
278                     }
279                 }
280 			}
281 		}
282 	}
283 	return bKeep;
284 }
285 
286 /*************************************************************************
287 |*
288 |*	SwFlowFrm::BwdMoveNecessary()
289 |*
290 |*	Ersterstellung		MA 20. Jul. 94
291 |*	Letzte Aenderung	MA 02. May. 96
292 |*
293 |*************************************************************************/
294 
295 
296 sal_uInt8 SwFlowFrm::BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect )
297 {
298 	// Der return-Wert entscheidet mit,
299 	// ob auf Zurueckgeflossen werden muss, (3)
300 	// ob das gute alte WouldFit gerufen werden kann (0, 1)
301 	// oder ob ein Umhaengen und eine Probeformatierung sinnvoll ist (2)
302 	// dabei bedeutet Bit 1, dass Objekte an mir selbst verankert sind
303 	// und Bit 2, dass ich anderen Objekten ausweichen muss.
304 
305 	//Wenn ein SurroundObj, dass einen Umfluss wuenscht mit dem Rect ueberlappt
306 	//ist der Fluss notwendig (weil die Verhaeltnisse nicht geschaetzt werden
307 	//koennen), es kann allerdings ggf. eine TestFormatierung stattfinden.
308 	//Wenn das SurroundObj ein Fly ist und ich selbst ein Lower bin oder der Fly
309 	//Lower von mir ist, so spielt er keine Rolle.
310 	//Wenn das SurroundObj in einem zeichengebunden Fly verankert ist, und ich
311 	//selbst nicht Lower dieses Zeichengebundenen Flys bin, so spielt der Fly
312 	//keine Rolle.
313 	//#32639# Wenn das Objekt bei mir verankert ist kann ich es
314 	//vernachlaessigen, weil es hoechstwahrscheinlich (!?) mitfliesst,
315 	//eine TestFormatierung ist dann allerdings nicht erlaubt!
316 	sal_uInt8 nRet = 0;
317 	SwFlowFrm *pTmp = this;
318 	do
319 	{   // Wenn an uns oder einem Follow Objekte haengen, so
320 		// kann keine ProbeFormatierung stattfinden, da absatzgebundene
321 		// nicht richtig beruecksichtigt wuerden und zeichengebundene sollten
322 		// gar nicht zur Probe formatiert werden.
323 		if( pTmp->GetFrm()->GetDrawObjs() )
324 			nRet = 1;
325 		pTmp = pTmp->GetFollow();
326 	} while ( !nRet && pTmp );
327 	if ( pPage->GetSortedObjs() )
328 	{
329         // --> OD 2004-07-01 #i28701# - new type <SwSortedObjs>
330         const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
331 		sal_uLong nIndex = ULONG_MAX;
332 		for ( sal_uInt16 i = 0; nRet < 3 && i < rObjs.Count(); ++i )
333 		{
334             // --> OD 2004-07-01 #i28701# - consider changed type of
335             // <SwSortedObjs> entries.
336             SwAnchoredObject* pObj = rObjs[i];
337             const SwFrmFmt& rFmt = pObj->GetFrmFmt();
338             const SwRect aRect( pObj->GetObjRect() );
339 			if ( aRect.IsOver( rRect ) &&
340                  rFmt.GetSurround().GetSurround() != SURROUND_THROUGHT )
341 			{
342 				if( rThis.IsLayoutFrm() && //Fly Lower von This?
343                     Is_Lower_Of( &rThis, pObj->GetDrawObj() ) )
344 					continue;
345                 if( pObj->ISA(SwFlyFrm) )
346 				{
347                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
348 					if ( pFly->IsAnLower( &rThis ) )//This Lower vom Fly?
349 						continue;
350 				}
351 
352                 const SwFrm* pAnchor = pObj->GetAnchorFrm();
353 				if ( pAnchor == &rThis )
354 				{
355 					nRet |= 1;
356 					continue;
357 				}
358 
359 				//Nicht wenn das Objekt im Textfluss hinter mir verankert ist,
360 				//denn dann weiche ich ihm nicht aus.
361 				if ( ::IsFrmInSameKontext( pAnchor, &rThis ) )
362 				{
363                     if ( rFmt.GetAnchor().GetAnchorId() == FLY_AT_PARA )
364 					{
365 						// Den Index des anderen erhalten wir immer ueber das Ankerattr.
366                         sal_uLong nTmpIndex = rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex();
367 						// Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem
368 						// Anker des verdraengenden Objekts im Text steht, dann wird
369 						// nicht ausgewichen.
370 						// Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt,
371 						// da sonst recht teuer.
372 						if( ULONG_MAX == nIndex )
373 						{
374 							const SwNode *pNode;
375 							if ( rThis.IsCntntFrm() )
376 								pNode = ((SwCntntFrm&)rThis).GetNode();
377 							else if( rThis.IsSctFrm() )
378 								pNode = ((SwSectionFmt*)((SwSectionFrm&)rThis).
379 										GetFmt())->GetSectionNode();
380 							else
381 							{
382 								ASSERT( rThis.IsTabFrm(), "new FowFrm?" );
383 								pNode = ((SwTabFrm&)rThis).GetTable()->
384 									GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
385 							}
386 							nIndex = pNode->GetIndex();
387 						}
388 						if( nIndex < nTmpIndex )
389 							continue;
390 					}
391 				}
392 				else
393 					continue;
394 
395 				nRet |= 2;
396 			}
397 		}
398 	}
399 	return nRet;
400 }
401 
402 /*************************************************************************
403 |*
404 |*	SwFlowFrm::CutTree(), PasteTree(), MoveSubTree()
405 |*
406 |*	Beschreibung		Eine Spezialisierte Form des Cut() und Paste(), die
407 |*		eine ganze Kette umhaengt (naehmlich this und folgende). Dabei werden
408 |* 		nur minimale Operationen und Benachrichtigungen ausgefuehrt.
409 |*	Ersterstellung		MA 18. Mar. 93
410 |*	Letzte Aenderung	MA 18. May. 95
411 |*
412 |*************************************************************************/
413 
414 
415 SwLayoutFrm *SwFlowFrm::CutTree( SwFrm *pStart )
416 {
417 	//Der Start und alle Nachbarn werden ausgeschnitten, sie werden aneinander-
418 	//gereiht und ein Henkel auf den ersten wird zurueckgeliefert.
419 	//Zurueckbleibende werden geeignet invalidiert.
420 
421 	SwLayoutFrm *pLay = pStart->GetUpper();
422 	if ( pLay->IsInFtn() )
423 		pLay = pLay->FindFtnFrm();
424 
425     // --> OD 2006-05-08 #i58846#
426     // <pPrepare( PREP_QUOVADIS )> only for frames in footnotes
427     if( pStart->IsInFtn() )
428 	{
429 		SwFrm* pTmp = pStart->GetIndPrev();
430 		if( pTmp )
431 			pTmp->Prepare( PREP_QUOVADIS );
432 	}
433     // <--
434 
435 	//Nur fix auschneiden und zwar so, dass klare Verhaeltnisse bei den
436 	//Verlassenen herrschen. Die Pointer der ausgeschnittenen Kette zeigen
437 	//noch wer weiss wo hin.
438 	if ( pStart == pStart->GetUpper()->Lower() )
439 		pStart->GetUpper()->pLower = 0;
440 	if ( pStart->GetPrev() )
441 	{
442 		pStart->GetPrev()->pNext = 0;
443 		pStart->pPrev = 0;
444 	}
445 
446 	if ( pLay->IsFtnFrm() )
447     {
448         if ( !pLay->Lower() && !pLay->IsColLocked() &&
449              !((SwFtnFrm*)pLay)->IsBackMoveLocked() )
450         {
451             pLay->Cut();
452 			delete pLay;
453 		}
454         else
455         {
456             sal_Bool bUnlock = !((SwFtnFrm*)pLay)->IsBackMoveLocked();
457             ((SwFtnFrm*)pLay)->LockBackMove();
458             pLay->InvalidateSize();
459             pLay->Calc();
460             SwCntntFrm *pCnt = pLay->ContainsCntnt();
461             while ( pCnt && pLay->IsAnLower( pCnt ) )
462             {
463                 //Kann sein, dass der CntFrm gelockt ist, wir wollen hier nicht
464                 //in eine endlose Seitenwanderung hineinlaufen und rufen das
465                 //Calc garnicht erst!
466                 ASSERT( pCnt->IsTxtFrm(), "Die Graphic ist gelandet." );
467                 if ( ((SwTxtFrm*)pCnt)->IsLocked() ||
468                      ((SwTxtFrm*)pCnt)->GetFollow() == pStart )
469                     break;
470                 pCnt->Calc();
471                 pCnt = pCnt->GetNextCntntFrm();
472             }
473             if( bUnlock )
474                 ((SwFtnFrm*)pLay)->UnlockBackMove();
475         }
476 		pLay = 0;
477 	}
478 	return pLay;
479 }
480 
481 
482 
483 sal_Bool SwFlowFrm::PasteTree( SwFrm *pStart, SwLayoutFrm *pParent, SwFrm *pSibling,
484 						   SwFrm *pOldParent )
485 {
486 	//returnt sal_True wenn in der Kette ein LayoutFrm steht.
487 	sal_Bool bRet = sal_False;
488 
489 	//Die mit pStart beginnende Kette wird vor den Sibling unter den Parent
490 	//gehaengt. Fuer geeignete Invalidierung wird ebenfalls gesorgt.
491 
492 	//Ich bekomme eine fertige Kette. Der Anfang der Kette muss verpointert
493 	//werden, dann alle Upper fuer die Kette und schliesslich dass Ende.
494 	//Unterwegs werden alle geeignet invalidiert.
495 	if ( pSibling )
496 	{
497 		if ( 0 != (pStart->pPrev = pSibling->GetPrev()) )
498 			pStart->GetPrev()->pNext = pStart;
499 		else
500 			pParent->pLower = pStart;
501 		pSibling->_InvalidatePos();
502 		pSibling->_InvalidatePrt();
503 	}
504 	else
505 	{
506         if ( 0 == (pStart->pPrev = pParent->Lower()) )
507             pParent->pLower = pStart;
508         else
509         //Modified for #i100782#,04/03/2009
510         //If the pParent has more than 1 child nodes, former design will
511         //ignore them directly without any collection work. It will make some
512         //dangling pointers. This lead the crash...
513         //The new design will find the last child of pParent in loop way, and
514         //add the pStart after the last child.
515         //  pParent->Lower()->pNext = pStart;
516         {
517             SwFrm* pTemp = pParent->pLower;
518             while (pTemp)
519             {
520                 if (pTemp->pNext)
521                     pTemp = pTemp->pNext;
522                 else
523                 {
524                     pStart->pPrev = pTemp;
525                     pTemp->pNext = pStart;
526                     break;
527                 }
528             }
529         }
530         //End modification for #i100782#,04/03/2009
531 
532         // #i27145#
533         if ( pParent->IsSctFrm() )
534         {
535             // We have no sibling because pParent is a section frame and
536             // has just been created to contain some content. The printing
537             // area of the frame behind pParent has to be invalidated, so
538             // that the correct distance between pParent and the next frame
539             // can be calculated.
540             pParent->InvalidateNextPrtArea();
541         }
542 	}
543 	SwFrm *pFloat = pStart;
544 	SwFrm *pLst = 0;
545     SWRECTFN( pParent )
546 	SwTwips nGrowVal = 0;
547 	do
548 	{	pFloat->pUpper = pParent;
549 		pFloat->_InvalidateAll();
550         pFloat->CheckDirChange();
551 
552 		//Ich bin Freund des TxtFrm und darf deshalb so einiges. Das mit
553 		//dem CacheIdx scheint etwas riskant!
554 		if ( pFloat->IsTxtFrm() )
555 		{
556 			if ( ((SwTxtFrm*)pFloat)->GetCacheIdx() != USHRT_MAX )
557 				((SwTxtFrm*)pFloat)->Init();	//Ich bin sein Freund.
558 		}
559 		else
560 			bRet = sal_True;
561 
562         nGrowVal += (pFloat->Frm().*fnRect->fnGetHeight)();
563 		if ( pFloat->GetNext() )
564 			pFloat = pFloat->GetNext();
565 		else
566 		{
567             pLst = pFloat;
568 			pFloat = 0;
569 		}
570 	} while ( pFloat );
571 
572 	if ( pSibling )
573 	{
574 		pLst->pNext = pSibling;
575 		pSibling->pPrev = pLst;
576 		if( pSibling->IsInFtn() )
577 		{
578 			if( pSibling->IsSctFrm() )
579 				pSibling = ((SwSectionFrm*)pSibling)->ContainsAny();
580 			if( pSibling )
581 				pSibling->Prepare( PREP_ERGOSUM );
582 		}
583 	}
584 	if ( nGrowVal )
585 	{
586 		if ( pOldParent && pOldParent->IsBodyFrm() ) //Fuer variable Seitenhoehe beim Browsen
587             pOldParent->Shrink( nGrowVal );
588         pParent->Grow( nGrowVal );
589 	}
590 
591 	if ( pParent->IsFtnFrm() )
592 		((SwFtnFrm*)pParent)->InvalidateNxtFtnCnts( pParent->FindPageFrm() );
593 	return bRet;
594 }
595 
596 
597 
598 void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling )
599 {
600 	ASSERT( pParent, "Kein Parent uebergeben." );
601 	ASSERT( rThis.GetUpper(), "Wo kommen wir denn her?" );
602 
603 	//Sparsamer benachrichtigen wenn eine Action laeuft.
604 	ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
605 	const SwViewImp *pImp = pSh ? pSh->Imp() : 0;
606 	const sal_Bool bComplete = pImp && pImp->IsAction() && pImp->GetLayAction().IsComplete();
607 
608 	if ( !bComplete )
609 	{
610 		SwFrm *pPre = rThis.GetIndPrev();
611 		if ( pPre )
612 		{
613 			pPre->SetRetouche();
614             // --> OD 2004-11-23 #115759# - follow-up of #i26250#
615             // invalidate printing area of previous frame, if it's in a table
616             if ( pPre->GetUpper()->IsInTab() )
617             {
618                 pPre->_InvalidatePrt();
619             }
620             // <--
621 			pPre->InvalidatePage();
622 		}
623 		else
624 		{	rThis.GetUpper()->SetCompletePaint();
625 			rThis.GetUpper()->InvalidatePage();
626 		}
627 	}
628 
629 	SwPageFrm *pOldPage = rThis.FindPageFrm();
630 
631 	SwLayoutFrm *pOldParent = CutTree( &rThis );
632 	const sal_Bool bInvaLay = PasteTree( &rThis, pParent, pSibling, pOldParent );
633 
634 	// Wenn durch das Cut&Paste ein leerer SectionFrm entstanden ist, sollte
635 	// dieser automatisch verschwinden.
636 	SwSectionFrm *pSct;
637     // --> OD 2006-01-04 #126020# - adjust check for empty section
638     // --> OD 2006-02-01 #130797# - correct fix #126020#
639 	if ( pOldParent && !pOldParent->Lower() &&
640          ( pOldParent->IsInSct() &&
641            !(pSct = pOldParent->FindSctFrm())->ContainsCntnt() &&
642            !pSct->ContainsAny( true ) ) )
643     // <--
644     {
645 			pSct->DelEmpty( sal_False );
646     }
647 
648     // In einem spaltigen Bereich rufen wir lieber kein Calc "von unten"
649     if( !rThis.IsInSct() &&
650         ( !rThis.IsInTab() || ( rThis.IsTabFrm() && !rThis.GetUpper()->IsInTab() ) ) )
651 		rThis.GetUpper()->Calc();
652     else if( rThis.GetUpper()->IsSctFrm() )
653 	{
654         SwSectionFrm* pTmpSct = (SwSectionFrm*)rThis.GetUpper();
655         sal_Bool bOld = pTmpSct->IsCntntLocked();
656         pTmpSct->SetCntntLock( sal_True );
657         pTmpSct->Calc();
658 		if( !bOld )
659             pTmpSct->SetCntntLock( sal_False );
660 	}
661 	SwPageFrm *pPage = rThis.FindPageFrm();
662 
663 	if ( pOldPage != pPage )
664 	{
665 		rThis.InvalidatePage( pPage );
666 		if ( rThis.IsLayoutFrm() )
667 		{
668 			SwCntntFrm *pCnt = ((SwLayoutFrm*)&rThis)->ContainsCntnt();
669 			if ( pCnt )
670 				pCnt->InvalidatePage( pPage );
671 		}
672 		else if ( pSh && pSh->GetDoc()->GetLineNumberInfo().IsRestartEachPage()
673 				  && pPage->FindFirstBodyCntnt() == &rThis )
674 		{
675 			rThis._InvalidateLineNum();
676 		}
677 	}
678 	if ( bInvaLay || (pSibling && pSibling->IsLayoutFrm()) )
679 		rThis.GetUpper()->InvalidatePage( pPage );
680 }
681 
682 /*************************************************************************
683 |*
684 |*	SwFlowFrm::IsAnFollow()
685 |*
686 |*	Ersterstellung		MA 26. Apr. 95
687 |*	Letzte Aenderung	MA 26. Apr. 95
688 |*
689 |*************************************************************************/
690 
691 
692 sal_Bool SwFlowFrm::IsAnFollow( const SwFlowFrm *pAssumed ) const
693 {
694 	const SwFlowFrm *pFoll = this;
695 	do
696 	{	if ( pAssumed == pFoll )
697 			return sal_True;
698 		pFoll = pFoll->GetFollow();
699 	} while ( pFoll );
700 	return sal_False;
701 }
702 
703 
704 /*************************************************************************
705 |*
706 |*	SwFlowFrm::FindMaster()
707 |*
708 |*	Ersterstellung		MA 26. Apr. 95
709 |*	Letzte Aenderung	MA 26. Apr. 95
710 |*
711 |*************************************************************************/
712 
713 SwTxtFrm* SwCntntFrm::FindMaster() const
714 {
715     ASSERT( IsFollow(), "SwCntntFrm::FindMaster(): !IsFollow" );
716 
717     const SwCntntFrm* pCnt = GetPrevCntntFrm();
718 
719     while ( pCnt )
720     {
721         if ( pCnt->HasFollow() && pCnt->GetFollow() == this )
722         {
723             ASSERT( pCnt->IsTxtFrm(), "NoTxtFrm with follow found" )
724             return (SwTxtFrm*)pCnt;
725         }
726         pCnt = pCnt->GetPrevCntntFrm();
727     }
728 
729     ASSERT( sal_False, "Follow ist lost in Space." );
730     return 0;
731 }
732 
733 SwSectionFrm* SwSectionFrm::FindMaster() const
734 {
735     ASSERT( IsFollow(), "SwSectionFrm::FindMaster(): !IsFollow" );
736 
737     SwIterator<SwSectionFrm,SwFmt> aIter( *pSection->GetFmt() );
738     SwSectionFrm* pSect = aIter.First();
739     while ( pSect )
740     {
741             if( pSect->GetFollow() == this )
742                 return pSect;
743         pSect = aIter.Next();
744     }
745 
746     ASSERT( sal_False, "Follow ist lost in Space." );
747     return 0;
748 }
749 
750 SwTabFrm* SwTabFrm::FindMaster( bool bFirstMaster ) const
751 {
752     ASSERT( IsFollow(), "SwTabFrm::FindMaster(): !IsFollow" );
753 
754     SwIterator<SwTabFrm,SwFmt> aIter( *GetTable()->GetFrmFmt() );
755     SwTabFrm* pTab = aIter.First();
756     while ( pTab )
757     {
758             if ( bFirstMaster )
759             {
760                 //
761                 // Optimization. This makes code like this obsolete:
762                 // while ( pTab->IsFollow() )
763                 //     pTab = pTab->FindMaster();
764                 //
765                 if ( !pTab->IsFollow() )
766                 {
767                     SwTabFrm* pNxt = pTab;
768                     while ( pNxt )
769                     {
770                         if ( pNxt->GetFollow() == this )
771                             return pTab;
772                         pNxt = pNxt->GetFollow();
773                     }
774                 }
775             }
776             else
777             {
778                 if ( pTab->GetFollow() == this )
779                     return pTab;
780             }
781 
782         pTab = aIter.Next();
783     }
784 
785     ASSERT( sal_False, "Follow ist lost in Space." );
786     return 0;
787 }
788 
789 /*************************************************************************
790 |*
791 |*	SwFrm::GetLeaf()
792 |*
793 |*	Beschreibung		Liefert das naechste/vorhergehende LayoutBlatt,
794 |* 		das _nicht_ unterhalb von this liegt (oder gar this selbst ist).
795 |* 		Ausserdem muss dieses LayoutBlatt im gleichen Textfluss wie
796 |* 		pAnch Ausgangsfrm liegen (Body, Ftn)
797 |*	Ersterstellung		MA 25. Nov. 92
798 |*	Letzte Aenderung	MA 25. Apr. 95
799 |*
800 |*************************************************************************/
801 
802 
803 const SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, sal_Bool bFwd,
804 								   const SwFrm *pAnch ) const
805 {
806 	//Ohne Fluss kein genuss...
807     if ( !(IsInDocBody() || IsInFtn() || IsInFly()) )
808         return 0;
809 
810 	const SwFrm *pLeaf = this;
811 	sal_Bool bFound = sal_False;
812 
813 	do
814 	{	pLeaf = ((SwFrm*)pLeaf)->GetLeaf( eMakePage, bFwd );
815 
816 		if ( pLeaf &&
817 			(!IsLayoutFrm() || !((SwLayoutFrm*)this)->IsAnLower( pLeaf )))
818 		{
819 			if ( pAnch->IsInDocBody() == pLeaf->IsInDocBody() &&
820 				 pAnch->IsInFtn()	  == pLeaf->IsInFtn() )
821 			{
822 				bFound = sal_True;
823 			}
824 		}
825 	} while ( !bFound && pLeaf );
826 
827 	return (const SwLayoutFrm*)pLeaf;
828 }
829 
830 /*************************************************************************
831 |*
832 |*	SwFrm::GetLeaf()
833 |*
834 |*	Beschreibung		Ruft Get[Next|Prev]Leaf
835 |*
836 |*	Ersterstellung		MA 20. Mar. 93
837 |*	Letzte Aenderung	MA 25. Apr. 95
838 |*
839 |*************************************************************************/
840 
841 
842 SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, sal_Bool bFwd )
843 {
844 	if ( IsInFtn() )
845 		return bFwd ? GetNextFtnLeaf( eMakePage ) : GetPrevFtnLeaf( eMakePage );
846 
847     // --> OD 2005-08-16 #i53323#
848     // A frame could be inside a table AND inside a section.
849     // Thus, it has to be determined, which is the first parent.
850     bool bInTab( IsInTab() );
851     bool bInSct( IsInSct() );
852     if ( bInTab && bInSct )
853     {
854         const SwFrm* pUpperFrm( GetUpper() );
855         while ( pUpperFrm )
856         {
857             if ( pUpperFrm->IsTabFrm() )
858             {
859                 // the table is the first.
860                 bInSct = false;
861                 break;
862             }
863             else if ( pUpperFrm->IsSctFrm() )
864             {
865                 // the section is the first.
866                 bInTab = false;
867                 break;
868             }
869 
870             pUpperFrm = pUpperFrm->GetUpper();
871         }
872     }
873 
874     if ( bInTab && ( !IsTabFrm() || GetUpper()->IsCellFrm() ) ) // TABLE IN TABLE
875         return bFwd ? GetNextCellLeaf( eMakePage ) : GetPrevCellLeaf( eMakePage );
876 
877     if ( bInSct )
878 		return bFwd ? GetNextSctLeaf( eMakePage ) : GetPrevSctLeaf( eMakePage );
879     // <--
880 
881 	return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf( eMakePage );
882 }
883 
884 
885 
886 sal_Bool SwFrm::WrongPageDesc( SwPageFrm* pNew )
887 {
888 	//Jetzt wirds leider etwas kompliziert:
889 	//Ich bringe ich evtl. selbst
890 	//einen Pagedesc mit; der der Folgeseite muss dann damit
891 	//uebereinstimmen.
892 	//Anderfalls muss ich mir etwas genauer ansehen wo der
893 	//Folgepagedesc herkam.
894 	//Wenn die Folgeseite selbst schon sagt, dass ihr
895 	//Pagedesc nicht stimmt so kann ich das Teil bedenkenlos
896 	//auswechseln.
897 	//Wenn die Seite meint, dass ihr Pagedesc stimmt, so heisst
898 	//das leider noch immer nicht, dass ich damit etwas anfangen
899 	//kann: Wenn der erste BodyCntnt einen PageDesc oder einen
900 	//PageBreak wuenscht, so muss ich ebenfalls eine neue
901 	//Seite einfuegen; es sein denn die gewuenschte Seite ist
902 	//die richtige.
903 	//Wenn ich einen neue Seite eingefuegt habe, so fangen die
904 	//Probleme leider erst an, denn wahrscheinlich wird die dann
905 	//folgende Seite verkehrt gewesen und ausgewechselt worden
906 	//sein. Das hat zur Folge, dass ich zwar eine neue (und
907 	//jetzt richtige) Seite habe, die Bedingungen zum auswechseln
908 	//aber leider noch immer stimmen.
909 	//Ausweg: Vorlaeufiger Versuch, nur einmal eine neue Seite
910 	//einsetzen (Leerseiten werden noetigenfalls bereits von
911 	//InsertPage() eingefuegt.
912 	const SwFmtPageDesc &rFmtDesc = GetAttrSet()->GetPageDesc();
913 
914 	//Mein Pagedesc zaehlt nicht, wenn ich ein Follow bin!
915 	SwPageDesc *pDesc = 0;
916 	sal_uInt16 nTmp = 0;
917 	SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( this );
918 	if ( !pFlow || !pFlow->IsFollow() )
919 	{
920 		pDesc = (SwPageDesc*)rFmtDesc.GetPageDesc();
921 		if( pDesc )
922 		{
923 			if( !pDesc->GetRightFmt() )
924 				nTmp = 2;
925 			else if( !pDesc->GetLeftFmt() )
926 				nTmp = 1;
927 			else if( rFmtDesc.GetNumOffset() )
928 				nTmp = rFmtDesc.GetNumOffset();
929 		}
930 	}
931 
932 	//Bringt der Cntnt einen Pagedesc mit oder muss zaehlt die
933 	//virtuelle Seitennummer des neuen Layoutleafs?
934 	// Bei Follows zaehlt der PageDesc nicht
935 	const sal_Bool bOdd = nTmp ? ( nTmp % 2 ? sal_True : sal_False )
936 						   : pNew->OnRightPage();
937 	if ( !pDesc )
938 		pDesc = pNew->FindPageDesc();
939 	const SwFlowFrm *pNewFlow = pNew->FindFirstBodyCntnt();
940 	// Haben wir uns selbst gefunden?
941 	if( pNewFlow == pFlow )
942 		pNewFlow = NULL;
943 	if ( pNewFlow && pNewFlow->GetFrm()->IsInTab() )
944 		pNewFlow = pNewFlow->GetFrm()->FindTabFrm();
945 	const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
946 			? pNewFlow->GetFrm()->GetAttrSet()->GetPageDesc().GetPageDesc():0;
947 
948 	return ( pNew->GetPageDesc() != pDesc ||   //  own desc ?
949 		pNew->GetFmt() != (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ||
950 		( pNewDesc && pNewDesc == pDesc ) );
951 }
952 
953 
954 /*************************************************************************
955 |*
956 |*	SwFrm::GetNextLeaf()
957 |*
958 |*	Beschreibung		Liefert das naechste LayoutBlatt in den das
959 |* 		Frame gemoved werden kann.
960 |*
961 |*	Ersterstellung		MA 16. Nov. 92
962 |*	Letzte Aenderung	MA 05. Dec. 96
963 |*
964 |*************************************************************************/
965 
966 SwLayoutFrm *SwFrm::GetNextLeaf( MakePageType eMakePage )
967 {
968 	ASSERT( !IsInFtn(), "GetNextLeaf(), don't call me for Ftn." );
969 	ASSERT( !IsInSct(), "GetNextLeaf(), don't call me for Sections." );
970 
971 	const sal_Bool bBody = IsInDocBody();		//Wenn ich aus dem DocBody komme
972 											//Will ich auch im Body landen.
973 
974 	// Bei Flys macht es keinen Sinn, Seiten einzufuegen, wir wollen lediglich
975 	 // die Verkettung absuchen.
976 	if( IsInFly() )
977 		eMakePage = MAKEPAGE_NONE;
978 
979     //Bei Tabellen gleich den grossen Sprung wagen, ein einfaches GetNext...
980 	//wuerde die erste Zellen und in der Folge alle weiteren Zellen nacheinander
981 	//abklappern....
982     SwLayoutFrm *pLayLeaf = 0;
983     if ( IsTabFrm() )
984     {
985         SwCntntFrm* pTmp = ((SwTabFrm*)this)->FindLastCntnt();
986         if ( pTmp )
987             pLayLeaf = pTmp->GetUpper();
988     }
989     if ( !pLayLeaf )
990         pLayLeaf = GetNextLayoutLeaf();
991 
992 	SwLayoutFrm *pOldLayLeaf = 0;			//Damit bei neu erzeugten Seiten
993 											//nicht wieder vom Anfang gesucht
994 											//wird.
995 	sal_Bool bNewPg = sal_False;	//nur einmal eine neue Seite einfuegen.
996 
997 	while ( sal_True )
998 	{
999 		if ( pLayLeaf )
1000 		{
1001 			//Es gibt noch einen weiteren LayoutFrm, mal sehen,
1002 			//ob er bereit ist mich aufzunehmen.
1003 			//Dazu braucht er nur von der gleichen Art wie mein Ausgangspunkt
1004 			//sein (DocBody bzw. Footnote.)
1005 			if ( pLayLeaf->FindPageFrm()->IsFtnPage() )
1006 			{	//Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
1007 				pLayLeaf = 0;
1008 				continue;
1009 			}
1010 			if ( (bBody && !pLayLeaf->IsInDocBody()) || pLayLeaf->IsInTab()
1011 				 || pLayLeaf->IsInSct() )
1012 			{
1013 				//Er will mich nicht; neuer Versuch, neues Glueck
1014 				pOldLayLeaf = pLayLeaf;
1015 				pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1016 				continue;
1017 			}
1018 			//Er will mich, also ist er der gesuchte und ich bin fertig.
1019 			//Bei einem Seitenwechsel kann es allerdings noch sein, dass
1020 			//Der Seitentyp nicht der gewuenschte ist, in diesem Fall muessen
1021 			//wir eine Seite des richtigen Typs einfuegen.
1022 
1023 			if( !IsFlowFrm() && ( eMakePage == MAKEPAGE_NONE ||
1024 				eMakePage==MAKEPAGE_APPEND || eMakePage==MAKEPAGE_NOSECTION ) )
1025 				return pLayLeaf;
1026 
1027 			SwPageFrm *pNew = pLayLeaf->FindPageFrm();
1028             const ViewShell *pSh = getRootFrm()->GetCurrShell();
1029             // #111704# The pagedesc check does not make sense for frames in fly frames
1030 			if ( pNew != FindPageFrm() && !bNewPg && !IsInFly() &&
1031                  // --> FME 2005-05-10 #i46683#
1032                  // Do not consider page descriptions in browse mode (since
1033                  // MoveBwd ignored them)
1034                  !(pSh && pSh->GetViewOptions()->getBrowseMode() ) )
1035                  // <--
1036 			{
1037 				if( WrongPageDesc( pNew ) )
1038 				{
1039 					SwFtnContFrm *pCont = pNew->FindFtnCont();
1040 					if( pCont )
1041 					{
1042 						// Falls die Referenz der ersten Fussnote dieser Seite
1043 						// vor der Seite liegt, fuegen wir lieber keine neue Seite
1044 						// ein (Bug #55620#)
1045 						SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower();
1046 						if( pFtn && pFtn->GetRef() )
1047 						{
1048 							const sal_uInt16 nRefNum = pNew->GetPhyPageNum();
1049 							if( pFtn->GetRef()->GetPhyPageNum() < nRefNum )
1050 								break;
1051 						}
1052 					}
1053 					//Erwischt, die folgende Seite ist verkehrt, also
1054 					//muss eine neue eingefuegt werden.
1055 					if ( eMakePage == MAKEPAGE_INSERT )
1056 					{
1057 						bNewPg = sal_True;
1058 
1059 						SwPageFrm *pPg = pOldLayLeaf ?
1060 									pOldLayLeaf->FindPageFrm() : 0;
1061 						if ( pPg && pPg->IsEmptyPage() )
1062 							//Nicht hinter, sondern vor der EmptyPage einfuegen.
1063 							pPg = (SwPageFrm*)pPg->GetPrev();
1064 
1065 						if ( !pPg || pPg == pNew )
1066 							pPg = FindPageFrm();
1067 
1068 						InsertPage( pPg, sal_False );
1069 						pLayLeaf = GetNextLayoutLeaf();
1070 						pOldLayLeaf = 0;
1071 						continue;
1072 					}
1073 					else
1074 						pLayLeaf = 0;
1075 				}
1076 			}
1077 			break;
1078 		}
1079 		else
1080 		{
1081 			//Es gibt keinen passenden weiteren LayoutFrm, also muss eine
1082 			//neue Seite her.
1083 			if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
1084 			{
1085 				InsertPage(
1086 					pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
1087 					sal_False );
1088 
1089 				//und nochmal das ganze
1090 				pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1091 			}
1092 			else
1093 				break;
1094 		}
1095 	}
1096 	return pLayLeaf;
1097 }
1098 
1099 /*************************************************************************
1100 |*
1101 |*	SwFrm::GetPrevLeaf()
1102 |*
1103 |*	Beschreibung		Liefert das vorhergehende LayoutBlatt in das der
1104 |* 		Frame gemoved werden kann.
1105 |*	Ersterstellung		MA 16. Nov. 92
1106 |*	Letzte Aenderung	MA 25. Apr. 95
1107 |*
1108 |*************************************************************************/
1109 
1110 
1111 SwLayoutFrm *SwFrm::GetPrevLeaf( MakePageType )
1112 {
1113 	ASSERT( !IsInFtn(), "GetPrevLeaf(), don't call me for Ftn." );
1114 
1115 	const sal_Bool bBody = IsInDocBody();		//Wenn ich aus dem DocBody komme
1116 											//will ich auch im Body landen.
1117 	const sal_Bool bFly  = IsInFly();
1118 
1119 	SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
1120 	SwLayoutFrm *pPrevLeaf = 0;
1121 
1122 	while ( pLayLeaf )
1123 	{
1124 		if ( pLayLeaf->IsInTab() || 	//In Tabellen geht's niemals hinein.
1125 			 pLayLeaf->IsInSct() )		//In Bereiche natuerlich auch nicht!
1126 			pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1127 		else if ( bBody && pLayLeaf->IsInDocBody() )
1128 		{
1129 			if ( pLayLeaf->Lower() )
1130 				break;
1131 			pPrevLeaf = pLayLeaf;
1132 			pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1133 			if ( pLayLeaf )
1134 				SwFlowFrm::SetMoveBwdJump( sal_True );
1135 		}
1136 		else if ( bFly )
1137 			break;	//Cntnts in Flys sollte jedes Layout-Blatt recht sein.
1138 		else
1139 			pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1140 	}
1141 	return pLayLeaf ? pLayLeaf : pPrevLeaf;
1142 }
1143 
1144 /*************************************************************************
1145 |*
1146 |*	SwFlowFrm::IsPrevObjMove()
1147 |*
1148 |*	Ersterstellung		MA 20. Feb. 96
1149 |*	Letzte Aenderung	MA 22. Feb. 96
1150 |*
1151 |*************************************************************************/
1152 
1153 
1154 sal_Bool SwFlowFrm::IsPrevObjMove() const
1155 {
1156 	//sal_True der FlowFrm soll auf einen Rahmen des Vorgaengers Ruecksicht nehmen
1157 	//     und fuer diesen ggf. Umbrechen.
1158 
1159 	//!!!!!!!!!!!Hack!!!!!!!!!!!
1160     const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
1161     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1162 		return sal_False;
1163 
1164 	SwFrm *pPre = rThis.FindPrev();
1165 
1166 	if ( pPre && pPre->GetDrawObjs() )
1167 	{
1168 		ASSERT( SwFlowFrm::CastFlowFrm( pPre ),	"new flowfrm?" );
1169 		if(	SwFlowFrm::CastFlowFrm( pPre )->IsAnFollow( this ) )
1170 			return sal_False;
1171         SwLayoutFrm* pPreUp = pPre->GetUpper();
1172 		// Wenn der Upper ein SectionFrm oder die Spalte eines SectionFrms ist,
1173 		// duerfen wir aus diesem durchaus heraushaengen,
1174 		// es muss stattdessen der Upper des SectionFrms beruecksichtigt werden.
1175 		if( pPreUp->IsInSct() )
1176 		{
1177 			if( pPreUp->IsSctFrm() )
1178 				pPreUp = pPreUp->GetUpper();
1179 			else if( pPreUp->IsColBodyFrm() &&
1180 					 pPreUp->GetUpper()->GetUpper()->IsSctFrm() )
1181                 pPreUp = pPreUp->GetUpper()->GetUpper()->GetUpper();
1182 		}
1183         // --> OD 2004-10-15 #i26945# - re-factoring:
1184         // use <GetVertPosOrientFrm()> to determine, if object has followed the
1185         // text flow to the next layout frame
1186 		for ( sal_uInt16 i = 0; i < pPre->GetDrawObjs()->Count(); ++i )
1187 		{
1188             // --> OD 2004-07-01 #i28701# - consider changed type of
1189             // <SwSortedObjs> entries.
1190             const SwAnchoredObject* pObj = (*pPre->GetDrawObjs())[i];
1191             // OD 2004-01-20 #110582# - do not consider hidden objects
1192             // --> OD 2004-10-15 #i26945# - do not consider object, which
1193             // doesn't follow the text flow.
1194             if ( pObj->GetFrmFmt().GetDoc()->IsVisibleLayerId(
1195                                             pObj->GetDrawObj()->GetLayer() ) &&
1196                  pObj->GetFrmFmt().GetFollowTextFlow().GetValue() )
1197             // <--
1198 			{
1199                 const SwLayoutFrm* pVertPosOrientFrm = pObj->GetVertPosOrientFrm();
1200                 if ( pVertPosOrientFrm &&
1201                      pPreUp != pVertPosOrientFrm &&
1202                      !pPreUp->IsAnLower( pVertPosOrientFrm ) )
1203                 {
1204                     return sal_True;
1205                 }
1206 			}
1207 		}
1208         // <--
1209 	}
1210 	return sal_False;
1211 }
1212 
1213 /*************************************************************************
1214 |*
1215 |*	sal_Bool SwFlowFrm::IsPageBreak()
1216 |*
1217 |*	Beschreibung		Wenn vor dem Frm ein harter Seitenumbruch steht UND
1218 |*		es einen Vorgaenger auf der gleichen Seite gibt, wird sal_True
1219 |*		zurueckgeliefert (es muss ein PageBreak erzeugt werden) sal_False sonst.
1220 |*		Wenn in bAct sal_True uebergeben wird, gibt die Funktion dann sal_True
1221 |*		zurueck, wenn ein PageBreak besteht.
1222 |* 		Fuer Follows wird der harte Seitenumbruch natuerlich nicht
1223 |* 		ausgewertet.
1224 |*		Der Seitenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
1225 |*		des Vorgaengers (AFTER). Wenn es keinen Vorgaenger auf der Seite
1226 |*		gibt ist jede weitere Ueberlegung ueberfluessig.
1227 |* 		Ein Seitenumbruch (oder der Bedarf) liegt auch dann vor, wenn
1228 |* 		im FrmFmt ein PageDesc angegeben wird.
1229 |*		Die Implementierung arbeitet zuaechst nur auf CntntFrms!
1230 |*		-->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
1231 |*	Ersterstellung		MA ??
1232 |*	Letzte Aenderung	MA 21. Mar. 95
1233 |*
1234 |*************************************************************************/
1235 
1236 
1237 sal_Bool SwFlowFrm::IsPageBreak( sal_Bool bAct ) const
1238 {
1239     if ( !IsFollow() && rThis.IsInDocBody() &&
1240          ( !rThis.IsInTab() || ( rThis.IsTabFrm() && !rThis.GetUpper()->IsInTab() ) ) ) // i66968
1241 	{
1242         const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
1243         if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1244             return sal_False;
1245         const SwAttrSet *pSet = rThis.GetAttrSet();
1246 
1247         //Vorgaenger ermitteln
1248 		const SwFrm *pPrev = rThis.FindPrev();
1249 		while ( pPrev && ( !pPrev->IsInDocBody() ||
1250 				( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
1251 			pPrev = pPrev->FindPrev();
1252 
1253 		if ( pPrev )
1254 		{
1255 			ASSERT( pPrev->IsInDocBody(), "IsPageBreak: Not in DocBody?" );
1256 			if ( bAct )
1257 			{	if ( rThis.FindPageFrm() == pPrev->FindPageFrm() )
1258 					return sal_False;
1259 			}
1260 			else
1261 			{	if ( rThis.FindPageFrm() != pPrev->FindPageFrm() )
1262 					return sal_False;
1263 			}
1264 
1265             const SvxBreak eBreak = pSet->GetBreak().GetBreak();
1266             if ( eBreak == SVX_BREAK_PAGE_BEFORE || eBreak == SVX_BREAK_PAGE_BOTH )
1267                 return sal_True;
1268             else
1269             {
1270                 const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
1271                 if ( ePrB == SVX_BREAK_PAGE_AFTER ||
1272                      ePrB == SVX_BREAK_PAGE_BOTH  ||
1273                      pSet->GetPageDesc().GetPageDesc() )
1274                     return sal_True;
1275             }
1276         }
1277     }
1278     return sal_False;
1279 }
1280 
1281 /*************************************************************************
1282 |*
1283 |*	sal_Bool SwFlowFrm::IsColBreak()
1284 |*
1285 |*	Beschreibung		Wenn vor dem Frm ein harter Spaltenumbruch steht UND
1286 |*		es einen Vorgaenger in der gleichen Spalte gibt, wird sal_True
1287 |*		zurueckgeliefert (es muss ein PageBreak erzeugt werden) sal_False sonst.
1288 |*		Wenn in bAct sal_True uebergeben wird, gibt die Funktion dann sal_True
1289 |*		zurueck, wenn ein ColBreak besteht.
1290 |* 		Fuer Follows wird der harte Spaltenumbruch natuerlich nicht
1291 |* 		ausgewertet.
1292 |*		Der Spaltenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
1293 |*		des Vorgaengers (AFTER). Wenn es keinen Vorgaenger in der Spalte
1294 |*		gibt ist jede weitere Ueberlegung ueberfluessig.
1295 |*		Die Implementierung arbeitet zuaechst nur auf CntntFrms!
1296 |*		-->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
1297 |*	Ersterstellung		MA 11. Jun. 93
1298 |*	Letzte Aenderung	MA 21. Mar. 95
1299 |*
1300 |*************************************************************************/
1301 
1302 sal_Bool SwFlowFrm::IsColBreak( sal_Bool bAct ) const
1303 {
1304 	if ( !IsFollow() && (rThis.IsMoveable() || bAct) )
1305 	{
1306 		const SwFrm *pCol = rThis.FindColFrm();
1307 		if ( pCol )
1308 		{
1309 			//Vorgaenger ermitteln
1310 			const SwFrm *pPrev = rThis.FindPrev();
1311 			while( pPrev && ( ( !pPrev->IsInDocBody() && !rThis.IsInFly() ) ||
1312 				   ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
1313 					pPrev = pPrev->FindPrev();
1314 
1315 			if ( pPrev )
1316 			{
1317 				if ( bAct )
1318 				{	if ( pCol == pPrev->FindColFrm() )
1319 						return sal_False;
1320 				}
1321 				else
1322 				{	if ( pCol != pPrev->FindColFrm() )
1323 						return sal_False;
1324 				}
1325 
1326                 const SvxBreak eBreak = rThis.GetAttrSet()->GetBreak().GetBreak();
1327                 if ( eBreak == SVX_BREAK_COLUMN_BEFORE ||
1328                      eBreak == SVX_BREAK_COLUMN_BOTH )
1329                     return sal_True;
1330                 else
1331                 {
1332                     const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
1333                     if ( ePrB == SVX_BREAK_COLUMN_AFTER ||
1334                          ePrB == SVX_BREAK_COLUMN_BOTH )
1335                         return sal_True;
1336                 }
1337             }
1338 		}
1339 	}
1340 	return sal_False;
1341 }
1342 
1343 sal_Bool SwFlowFrm::HasParaSpaceAtPages( sal_Bool bSct ) const
1344 {
1345 	if( rThis.IsInSct() )
1346 	{
1347 		const SwFrm* pTmp = rThis.GetUpper();
1348 		while( pTmp )
1349 		{
1350 			if( pTmp->IsCellFrm() || pTmp->IsFlyFrm() ||
1351 				pTmp->IsFooterFrm() || pTmp->IsHeaderFrm() ||
1352 				( pTmp->IsFtnFrm() && !((SwFtnFrm*)pTmp)->GetMaster() ) )
1353 				return sal_True;
1354 			if( pTmp->IsPageFrm() )
1355 				return ( pTmp->GetPrev() && !IsPageBreak(sal_True) ) ? sal_False : sal_True;
1356 			if( pTmp->IsColumnFrm() && pTmp->GetPrev() )
1357 				return IsColBreak( sal_True );
1358 			if( pTmp->IsSctFrm() && ( !bSct || pTmp->GetPrev() ) )
1359 				return sal_False;
1360 			pTmp = pTmp->GetUpper();
1361 		}
1362 		ASSERT( sal_False, "HasParaSpaceAtPages: Where's my page?" );
1363 		return sal_False;
1364 	}
1365 	if( !rThis.IsInDocBody() || ( rThis.IsInTab() && !rThis.IsTabFrm()) ||
1366 		IsPageBreak( sal_True ) || ( rThis.FindColFrm() && IsColBreak( sal_True ) ) )
1367 		return sal_True;
1368 	const SwFrm* pTmp = rThis.FindColFrm();
1369 	if( pTmp )
1370 	{
1371 		if( pTmp->GetPrev() )
1372 			return sal_False;
1373 	}
1374 	else
1375 		pTmp = &rThis;
1376 	pTmp = pTmp->FindPageFrm();
1377 	return pTmp && !pTmp->GetPrev();
1378 }
1379 
1380 /** helper method to determine previous frame for calculation of the
1381     upper space
1382 
1383     OD 2004-03-10 #i11860#
1384 
1385     @author OD
1386 */
1387 const SwFrm* SwFlowFrm::_GetPrevFrmForUpperSpaceCalc( const SwFrm* _pProposedPrevFrm ) const
1388 {
1389     const SwFrm* pPrevFrm = _pProposedPrevFrm
1390                             ? _pProposedPrevFrm
1391                             : rThis.GetPrev();
1392 
1393     // Skip hidden paragraphs and empty sections
1394     while ( pPrevFrm &&
1395             ( ( pPrevFrm->IsTxtFrm() &&
1396                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ||
1397               ( pPrevFrm->IsSctFrm() &&
1398                 !static_cast<const SwSectionFrm*>(pPrevFrm)->GetSection() ) ) )
1399     {
1400         pPrevFrm = pPrevFrm->GetPrev();
1401     }
1402 
1403     // Special case: no direct previous frame is found but frame is in footnote
1404     // Search for a previous frame in previous footnote,
1405     // if frame isn't in a section, which is also in the footnote
1406     if ( !pPrevFrm && rThis.IsInFtn() &&
1407          ( rThis.IsSctFrm() ||
1408            !rThis.IsInSct() || !rThis.FindSctFrm()->IsInFtn() ) )
1409     {
1410         const SwFtnFrm* pPrevFtnFrm =
1411                 static_cast<const SwFtnFrm*>(rThis.FindFtnFrm()->GetPrev());
1412         if ( pPrevFtnFrm )
1413         {
1414             pPrevFrm = pPrevFtnFrm->GetLastLower();
1415 
1416             // Skip hidden paragraphs and empty sections
1417             while ( pPrevFrm &&
1418                     ( ( pPrevFrm->IsTxtFrm() &&
1419                         static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ||
1420                       ( pPrevFrm->IsSctFrm() &&
1421                         !static_cast<const SwSectionFrm*>(pPrevFrm)->GetSection() ) ) )
1422             {
1423                 pPrevFrm = pPrevFrm->GetPrev();
1424             }
1425         }
1426     }
1427     // Special case: found previous frame is a section
1428     // Search for the last content in the section
1429     if( pPrevFrm && pPrevFrm->IsSctFrm() )
1430     {
1431         const SwSectionFrm* pPrevSectFrm =
1432                                     static_cast<const SwSectionFrm*>(pPrevFrm);
1433         pPrevFrm = pPrevSectFrm->FindLastCntnt();
1434         // If the last content is in a table _inside_ the section,
1435         // take the table herself.
1436         // OD 2004-02-18 #106629# - correction:
1437         // Check directly, if table is inside table, instead of indirectly
1438         // by checking, if section isn't inside a table
1439         if ( pPrevFrm && pPrevFrm->IsInTab() )
1440         {
1441             const SwTabFrm* pTableFrm = pPrevFrm->FindTabFrm();
1442             if ( pPrevSectFrm->IsAnLower( pTableFrm ) )
1443             {
1444                 pPrevFrm = pTableFrm;
1445             }
1446         }
1447         // OD 2004-02-18 #106629# correction: skip hidden text frames
1448         while ( pPrevFrm &&
1449                 pPrevFrm->IsTxtFrm() &&
1450                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
1451         {
1452             pPrevFrm = pPrevFrm->GetPrev();
1453         }
1454     }
1455 
1456     return pPrevFrm;
1457 }
1458 
1459 // OD 2004-03-12 #i11860# - add 3rd parameter <_bConsiderGrid>
1460 SwTwips SwFlowFrm::CalcUpperSpace( const SwBorderAttrs *pAttrs,
1461                                    const SwFrm* pPr,
1462                                    const bool _bConsiderGrid ) const
1463 {
1464     // OD 2004-03-10 #i11860# - use new method <GetPrevFrmForUpperSpaceCalc(..)>
1465     const SwFrm* pPrevFrm = _GetPrevFrmForUpperSpaceCalc( pPr );
1466 
1467     SwBorderAttrAccess *pAccess;
1468 	SwFrm* pOwn;
1469 	if( !pAttrs )
1470 	{
1471 		if( rThis.IsSctFrm() )
1472 		{
1473 			SwSectionFrm* pFoll = &((SwSectionFrm&)rThis);
1474 			do
1475 				pOwn = pFoll->ContainsAny();
1476 			while( !pOwn && 0 != ( pFoll = pFoll->GetFollow() ) );
1477 			if( !pOwn )
1478 				return 0;
1479 		}
1480 		else
1481 			pOwn = &rThis;
1482 		pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), pOwn );
1483 		pAttrs = pAccess->Get();
1484 	}
1485 	else
1486 	{
1487 		pAccess = NULL;
1488 		pOwn = &rThis;
1489 	}
1490 	SwTwips nUpper = 0;
1491     // OD 06.01.2004 #i11859#
1492     {
1493         const IDocumentSettingAccess* pIDSA = rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess();
1494         const bool bUseFormerLineSpacing = pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING);
1495         if( pPrevFrm )
1496         {
1497             // OD 2004-03-10 #i11860# - use new method to determine needed spacing
1498             // values of found previous frame and use these values.
1499             SwTwips nPrevLowerSpace = 0;
1500             SwTwips nPrevLineSpacing = 0;
1501             // --> OD 2009-08-28 #i102458#
1502             bool bPrevLineSpacingPorportional = false;
1503             GetSpacingValuesOfFrm( (*pPrevFrm),
1504                                    nPrevLowerSpace, nPrevLineSpacing,
1505                                    bPrevLineSpacingPorportional );
1506             // <--
1507             if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) )
1508             {
1509                 nUpper = nPrevLowerSpace + pAttrs->GetULSpace().GetUpper();
1510                 SwTwips nAdd = nPrevLineSpacing;
1511                 // OD 07.01.2004 #i11859# - consideration of the line spacing
1512                 //      for the upper spacing of a text frame
1513                 if ( bUseFormerLineSpacing )
1514                 {
1515                     // former consideration
1516                     if ( pOwn->IsTxtFrm() )
1517                     {
1518                         nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace() );
1519                     }
1520                     nUpper += nAdd;
1521                 }
1522                 else
1523                 {
1524                     // new consideration:
1525                     //      Only the proportional line spacing of the previous
1526                     //      text frame is considered for the upper spacing and
1527                     //      the line spacing values are add up instead of
1528                     //      building its maximum.
1529                     if ( pOwn->IsTxtFrm() )
1530                     {
1531                         // --> OD 2009-08-28 #i102458#
1532                         // Correction:
1533                         // A proportional line spacing of the previous text frame
1534                         // is added up to a own leading line spacing.
1535                         // Otherwise, the maximum of the leading line spacing
1536                         // of the previous text frame and the own leading line
1537                         // spacing is built.
1538                         if ( bPrevLineSpacingPorportional )
1539                         {
1540                             nAdd += static_cast<SwTxtFrm&>(rThis).GetLineSpace( true );
1541                         }
1542                         else
1543                         {
1544                             nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace( true ) );
1545                         }
1546                         // <--
1547                     }
1548                     nUpper += nAdd;
1549                 }
1550             }
1551             else
1552             {
1553                 nUpper = Max( static_cast<long>(nPrevLowerSpace),
1554                               static_cast<long>(pAttrs->GetULSpace().GetUpper()) );
1555                 // OD 07.01.2004 #i11859# - consideration of the line spacing
1556                 //      for the upper spacing of a text frame
1557                 if ( bUseFormerLineSpacing )
1558                 {
1559                     // former consideration
1560                     if ( pOwn->IsTxtFrm() )
1561                         nUpper = Max( nUpper, ((SwTxtFrm*)pOwn)->GetLineSpace() );
1562                     if ( nPrevLineSpacing != 0 )
1563                     {
1564                         nUpper = Max( nUpper, nPrevLineSpacing );
1565                     }
1566                 }
1567                 else
1568                 {
1569                     // new consideration:
1570                     //      Only the proportional line spacing of the previous
1571                     //      text frame is considered for the upper spacing and
1572                     //      the line spacing values are add up and added to
1573                     //      the paragraph spacing instead of building the
1574                     //      maximum of the line spacings and the paragraph spacing.
1575                     SwTwips nAdd = nPrevLineSpacing;
1576                     if ( pOwn->IsTxtFrm() )
1577                     {
1578                         // --> OD 2009-08-28 #i102458#
1579                         // Correction:
1580                         // A proportional line spacing of the previous text frame
1581                         // is added up to a own leading line spacing.
1582                         // Otherwise, the maximum of the leading line spacing
1583                         // of the previous text frame and the own leading line
1584                         // spacing is built.
1585                         if ( bPrevLineSpacingPorportional )
1586                         {
1587                             nAdd += static_cast<SwTxtFrm&>(rThis).GetLineSpace( true );
1588                         }
1589                         else
1590                         {
1591                             nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace( true ) );
1592                         }
1593                         // <--
1594                     }
1595                     nUpper += nAdd;
1596                 }
1597             }
1598         }
1599         else if ( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) &&
1600                   CastFlowFrm( pOwn )->HasParaSpaceAtPages( rThis.IsSctFrm() ) )
1601         {
1602             nUpper = pAttrs->GetULSpace().GetUpper();
1603         }
1604     }
1605 
1606     // OD 2004-02-26 #i25029# - pass previous frame <pPrevFrm>
1607     // to method <GetTopLine(..)>, if parameter <pPr> is set.
1608     // Note: parameter <pPr> is set, if method is called from <SwTxtFrm::WouldFit(..)>
1609     nUpper += pAttrs->GetTopLine( rThis, (pPr ? pPrevFrm : 0L) );
1610 
1611     // OD 2004-03-12 #i11860# - consider value of new parameter <_bConsiderGrid>
1612     // and use new method <GetUpperSpaceAmountConsideredForPageGrid(..)>
1613 
1614 	//consider grid in square page mode
1615     if ( _bConsiderGrid && rThis.GetUpper()->GetFmt()->GetDoc()->IsSquaredPageMode() )
1616     {
1617         nUpper += _GetUpperSpaceAmountConsideredForPageGrid( nUpper );
1618     }
1619 
1620 	delete pAccess;
1621 	return nUpper;
1622 }
1623 
1624 /** method to detemine the upper space amount, which is considered for
1625     the page grid
1626 
1627     OD 2004-03-12 #i11860#
1628     Precondition: Position of frame is valid.
1629 
1630     @author OD
1631 */
1632 SwTwips SwFlowFrm::_GetUpperSpaceAmountConsideredForPageGrid(
1633                             const SwTwips _nUpperSpaceWithoutGrid ) const
1634 {
1635     SwTwips nUpperSpaceAmountConsideredForPageGrid = 0;
1636 
1637     if ( rThis.IsInDocBody() && rThis.GetAttrSet()->GetParaGrid().GetValue() )
1638     {
1639         const SwPageFrm* pPageFrm = rThis.FindPageFrm();
1640         GETGRID( pPageFrm )
1641         if( pGrid )
1642         {
1643             const SwFrm* pBodyFrm = pPageFrm->FindBodyCont();
1644             if ( pBodyFrm )
1645             {
1646                 const long nGridLineHeight =
1647                         pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
1648 
1649                 SWRECTFN( (&rThis) )
1650                 const SwTwips nBodyPrtTop = (pBodyFrm->*fnRect->fnGetPrtTop)();
1651                 const SwTwips nProposedPrtTop =
1652                         (*fnRect->fnYInc)( (rThis.Frm().*fnRect->fnGetTop)(),
1653                                            _nUpperSpaceWithoutGrid );
1654 
1655                 const SwTwips nSpaceAbovePrtTop =
1656                         (*fnRect->fnYDiff)( nProposedPrtTop, nBodyPrtTop );
1657                 const SwTwips nSpaceOfCompleteLinesAbove =
1658                         nGridLineHeight * ( nSpaceAbovePrtTop / nGridLineHeight );
1659                 SwTwips nNewPrtTop =
1660                         (*fnRect->fnYInc)( nBodyPrtTop, nSpaceOfCompleteLinesAbove );
1661                 if ( (*fnRect->fnYDiff)( nProposedPrtTop, nNewPrtTop ) > 0 )
1662                 {
1663                     nNewPrtTop = (*fnRect->fnYInc)( nNewPrtTop, nGridLineHeight );
1664                 }
1665 
1666                 const SwTwips nNewUpperSpace =
1667                         (*fnRect->fnYDiff)( nNewPrtTop,
1668                                             (rThis.Frm().*fnRect->fnGetTop)() );
1669 
1670                 nUpperSpaceAmountConsideredForPageGrid =
1671                         nNewUpperSpace - _nUpperSpaceWithoutGrid;
1672 
1673                 ASSERT( nUpperSpaceAmountConsideredForPageGrid >= 0,
1674                         "<SwFlowFrm::GetUpperSpaceAmountConsideredForPageGrid(..)> - negative space considered for page grid!" );
1675             }
1676         }
1677     }
1678     return nUpperSpaceAmountConsideredForPageGrid;
1679 }
1680 
1681 /** method to determent the upper space amount, which is considered for
1682     the previous frame
1683 
1684     OD 2004-03-11 #i11860#
1685 
1686     @author OD
1687 */
1688 SwTwips SwFlowFrm::_GetUpperSpaceAmountConsideredForPrevFrm() const
1689 {
1690     SwTwips nUpperSpaceAmountOfPrevFrm = 0;
1691 
1692     const SwFrm* pPrevFrm = _GetPrevFrmForUpperSpaceCalc();
1693     if ( pPrevFrm )
1694     {
1695         SwTwips nPrevLowerSpace = 0;
1696         SwTwips nPrevLineSpacing = 0;
1697         // --> OD 2009-08-28 #i102458#
1698         bool bDummy = false;
1699         GetSpacingValuesOfFrm( (*pPrevFrm), nPrevLowerSpace, nPrevLineSpacing, bDummy );
1700         // <--
1701         if ( nPrevLowerSpace > 0 || nPrevLineSpacing > 0 )
1702         {
1703             const IDocumentSettingAccess* pIDSA = rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess();
1704             if (  pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
1705                  !pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
1706             {
1707                 nUpperSpaceAmountOfPrevFrm = nPrevLowerSpace + nPrevLineSpacing;
1708             }
1709             else
1710             {
1711                 nUpperSpaceAmountOfPrevFrm = Max( nPrevLowerSpace, nPrevLineSpacing );
1712             }
1713         }
1714     }
1715 
1716     return nUpperSpaceAmountOfPrevFrm;
1717 }
1718 
1719 /** method to determine the upper space amount, which is considered for
1720     the previous frame and the page grid, if option 'Use former object
1721     positioning' is OFF
1722 
1723     OD 2004-03-18 #i11860#
1724 
1725     @author OD
1726 */
1727 SwTwips SwFlowFrm::GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() const
1728 {
1729     SwTwips nUpperSpaceAmountConsideredForPrevFrmAndPageGrid = 0;
1730 
1731     if ( !rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
1732     {
1733         nUpperSpaceAmountConsideredForPrevFrmAndPageGrid =
1734             _GetUpperSpaceAmountConsideredForPrevFrm() +
1735             _GetUpperSpaceAmountConsideredForPageGrid( CalcUpperSpace( 0L, 0L, false ) );
1736     }
1737 
1738     return nUpperSpaceAmountConsideredForPrevFrmAndPageGrid;
1739 }
1740 
1741 /** calculation of lower space
1742 
1743     OD 2004-03-02 #106629#
1744 
1745     @author OD
1746 */
1747 SwTwips SwFlowFrm::CalcLowerSpace( const SwBorderAttrs* _pAttrs ) const
1748 {
1749     SwTwips nLowerSpace = 0;
1750 
1751     SwBorderAttrAccess* pAttrAccess = 0L;
1752     if ( !_pAttrs )
1753     {
1754         pAttrAccess = new SwBorderAttrAccess( SwFrm::GetCache(), &rThis );
1755         _pAttrs = pAttrAccess->Get();
1756     }
1757 
1758     sal_Bool bCommonBorder = sal_True;
1759     if ( rThis.IsInSct() && rThis.GetUpper()->IsColBodyFrm() )
1760     {
1761         const SwSectionFrm* pSectFrm = rThis.FindSctFrm();
1762         bCommonBorder = pSectFrm->GetFmt()->GetBalancedColumns().GetValue();
1763     }
1764     nLowerSpace = bCommonBorder ?
1765                   _pAttrs->GetBottomLine( rThis ) :
1766                   _pAttrs->CalcBottomLine();
1767 
1768     // --> OD 2004-07-16 #i26250#
1769     // - correct consideration of table frames
1770     // - use new method <CalcAddLowerSpaceAsLastInTableCell(..)>
1771     if ( ( ( rThis.IsTabFrm() && rThis.GetUpper()->IsInTab() ) ||
1772            // --> OD 2004-11-16 #115759# - no lower spacing, if frame has a follow
1773            ( rThis.IsInTab() && !GetFollow() ) ) &&
1774            // <--
1775          !rThis.GetIndNext() )
1776     {
1777         nLowerSpace += CalcAddLowerSpaceAsLastInTableCell( _pAttrs );
1778     }
1779     // <--
1780 
1781     delete pAttrAccess;
1782 
1783     return nLowerSpace;
1784 }
1785 
1786 /** calculation of the additional space to be considered, if flow frame
1787     is the last inside a table cell
1788 
1789     OD 2004-07-16 #i26250#
1790 
1791     @author OD
1792 */
1793 SwTwips SwFlowFrm::CalcAddLowerSpaceAsLastInTableCell(
1794                                             const SwBorderAttrs* _pAttrs ) const
1795 {
1796     SwTwips nAdditionalLowerSpace = 0;
1797 
1798     if ( rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
1799     {
1800         const SwFrm* pFrm = &rThis;
1801         if ( pFrm->IsSctFrm() )
1802         {
1803             const SwSectionFrm* pSectFrm = static_cast<const SwSectionFrm*>(pFrm);
1804             pFrm = pSectFrm->FindLastCntnt();
1805             if ( pFrm && pFrm->IsInTab() )
1806             {
1807                 const SwTabFrm* pTableFrm = pFrm->FindTabFrm();
1808                 if ( pSectFrm->IsAnLower( pTableFrm ) )
1809                 {
1810                     pFrm = pTableFrm;
1811                 }
1812             }
1813         }
1814 
1815         SwBorderAttrAccess* pAttrAccess = 0L;
1816         if ( !_pAttrs || pFrm != &rThis )
1817         {
1818             pAttrAccess = new SwBorderAttrAccess( SwFrm::GetCache(), pFrm );
1819             _pAttrs = pAttrAccess->Get();
1820         }
1821 
1822         nAdditionalLowerSpace += _pAttrs->GetULSpace().GetLower();
1823 
1824         delete pAttrAccess;
1825     }
1826 
1827     return nAdditionalLowerSpace;
1828 }
1829 
1830 /*************************************************************************
1831 |*
1832 |*	sal_Bool SwFlowFrm::CheckMoveFwd()
1833 |*
1834 |*	Beschreibung		Moved den Frm vorwaerts wenn es durch die aktuellen
1835 |* 		Bedingungen und Attribute notwendig erscheint.
1836 |*	Ersterstellung		MA 05. Dec. 96
1837 |*	Letzte Aenderung	MA 09. Mar. 98
1838 |*
1839 |*************************************************************************/
1840 
1841 
1842 sal_Bool SwFlowFrm::CheckMoveFwd( sal_Bool &rbMakePage, sal_Bool bKeep, sal_Bool )
1843 {
1844 	const SwFrm* pNxt = rThis.GetIndNext();
1845 
1846 	if ( bKeep && //!bMovedBwd &&
1847 		 ( !pNxt || ( pNxt->IsTxtFrm() && ((SwTxtFrm*)pNxt)->IsEmptyMaster() ) ) &&
1848 		 ( 0 != (pNxt = rThis.FindNext()) ) && IsKeepFwdMoveAllowed() )
1849 	{
1850 		if( pNxt->IsSctFrm() )
1851 		{   // Nicht auf leere SectionFrms hereinfallen
1852 			const SwFrm* pTmp = NULL;
1853 			while( pNxt && pNxt->IsSctFrm() &&
1854 				   ( !((SwSectionFrm*)pNxt)->GetSection() ||
1855 					 0 == ( pTmp = ((SwSectionFrm*)pNxt)->ContainsAny() ) ) )
1856 			{
1857 				pNxt = pNxt->FindNext();
1858 				pTmp = NULL;
1859 			}
1860 			if( pTmp )
1861 				pNxt = pTmp; // the content of the next notempty sectionfrm
1862 		}
1863 		if( pNxt && pNxt->GetValidPosFlag() )
1864 		{
1865 			sal_Bool bMove = sal_False;
1866 			const SwSectionFrm *pSct = rThis.FindSctFrm();
1867 			if( pSct && !pSct->GetValidSizeFlag() )
1868 			{
1869 				const SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
1870 				if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
1871 					bMove = sal_True;
1872 			}
1873 			else
1874 				bMove = sal_True;
1875 			if( bMove )
1876 			{
1877 				//Keep together with the following frame
1878 				MoveFwd( rbMakePage, sal_False );
1879 				return sal_True;
1880 			}
1881 		}
1882 	}
1883 
1884 	sal_Bool bMovedFwd = sal_False;
1885 
1886 	if ( rThis.GetIndPrev() )
1887 	{
1888 		if ( IsPrevObjMove() ) //Auf Objekte des Prev Ruecksicht nehmen?
1889 		{
1890 			bMovedFwd = sal_True;
1891 			if ( !MoveFwd( rbMakePage, sal_False ) )
1892 				rbMakePage = sal_False;
1893 		}
1894 		else
1895 		{
1896 			if ( IsPageBreak( sal_False ) )
1897 			{
1898 				while ( MoveFwd( rbMakePage, sal_True ) )
1899 						/* do nothing */;
1900 				rbMakePage = sal_False;
1901 				bMovedFwd = sal_True;
1902 			}
1903 			else if ( IsColBreak ( sal_False ) )
1904 			{
1905 				const SwPageFrm *pPage = rThis.FindPageFrm();
1906 				SwFrm *pCol = rThis.FindColFrm();
1907 				do
1908 				{	MoveFwd( rbMakePage, sal_False );
1909 					SwFrm *pTmp = rThis.FindColFrm();
1910 					if( pTmp != pCol )
1911 					{
1912 						bMovedFwd = sal_True;
1913 						pCol = pTmp;
1914 					}
1915 					else
1916 						break;
1917 				} while ( IsColBreak( sal_False ) );
1918 				if ( pPage != rThis.FindPageFrm() )
1919 					rbMakePage = sal_False;
1920 			}
1921 		}
1922 	}
1923 	return bMovedFwd;
1924 }
1925 
1926 /*************************************************************************
1927 |*
1928 |*	sal_Bool SwFlowFrm::MoveFwd()
1929 |*
1930 |*	Beschreibung		Returnwert sagt, ob der Frm die Seite gewechselt hat.
1931 |*	Ersterstellung		MA 05. Dec. 96
1932 |*	Letzte Aenderung	MA 05. Dec. 96
1933 |*
1934 |*************************************************************************/
1935 
1936 
1937 sal_Bool SwFlowFrm::MoveFwd( sal_Bool bMakePage, sal_Bool bPageBreak, sal_Bool bMoveAlways )
1938 {
1939 //!!!!MoveFtnCntFwd muss ggf. mitgepflegt werden.
1940 	SwFtnBossFrm *pOldBoss = rThis.FindFtnBossFrm();
1941 	if ( rThis.IsInFtn() )
1942 		return ((SwCntntFrm&)rThis).MoveFtnCntFwd( bMakePage, pOldBoss );
1943 
1944 	if( !IsFwdMoveAllowed() && !bMoveAlways )
1945 	{
1946 		sal_Bool bNoFwd = sal_True;
1947 		if( rThis.IsInSct() )
1948 		{
1949 			SwFtnBossFrm* pBoss = rThis.FindFtnBossFrm();
1950 			bNoFwd = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() &&
1951 					 !pBoss->GetPrev() );
1952 		}
1953 
1954         // Allow the MoveFwd even if we do not have an IndPrev in these cases:
1955         if ( rThis.IsInTab() &&
1956             ( !rThis.IsTabFrm() ||
1957                 ( rThis.GetUpper()->IsInTab() &&
1958                   rThis.GetUpper()->FindTabFrm()->IsFwdMoveAllowed() ) ) &&
1959              0 != const_cast<SwFrm&>(rThis).GetNextCellLeaf( MAKEPAGE_NONE ) )
1960 /*
1961               &&
1962             // NEW TABLES
1963             // Have a look at our main competitor: We don't move inside row span cells:
1964             ( !rThis.GetUpper()->IsCellFrm() || !rThis.GetUpper()->IsLeaveUpperAllowed() ) )*/
1965         {
1966             bNoFwd = sal_False;
1967         }
1968 
1969         if( bNoFwd )
1970 		{
1971 			//Fuer PageBreak ist das Moven erlaubt, wenn der Frm nicht
1972 			//bereits der erste der Seite ist.
1973 			if ( !bPageBreak )
1974 				return sal_False;
1975 
1976 			const SwFrm *pCol = rThis.FindColFrm();
1977 			if ( !pCol || !pCol->GetPrev() )
1978 				return sal_False;
1979 		}
1980 	}
1981 
1982 	sal_Bool bSamePage = sal_True;
1983 	SwLayoutFrm *pNewUpper =
1984 			rThis.GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, sal_True );
1985 
1986 	if ( pNewUpper )
1987 	{
1988 		PROTOCOL_ENTER( &rThis, PROT_MOVE_FWD, 0, 0 );
1989 		SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
1990 		//Wir moven uns und alle direkten Nachfolger vor den ersten
1991 		//CntntFrm unterhalb des neuen Uppers.
1992 
1993 		// Wenn unser NewUpper in einem SectionFrm liegt, muessen wir
1994 		// verhindern, dass sich dieser im Calc selbst zerstoert
1995 		SwSectionFrm* pSect = pNewUpper->FindSctFrm();
1996 		sal_Bool bUnlock = sal_False;
1997 		if( pSect )
1998 		{
1999 			// Wenn wir nur innerhalb unseres SectionFrms die Spalte wechseln,
2000 			// rufen wir lieber kein Calc, sonst wird noch der SectionFrm
2001 			// formatiert, der wiederum uns ruft etc.
2002 			if( pSect != rThis.FindSctFrm() )
2003 			{
2004 				bUnlock = !pSect->IsColLocked();
2005 				pSect->ColLock();
2006 				pNewUpper->Calc();
2007 				if( bUnlock )
2008 					pSect->ColUnlock();
2009 			}
2010 		}
2011         // Do not calculate split cell frames.
2012 		else if ( !pNewUpper->IsCellFrm() || ((SwLayoutFrm*)pNewUpper)->Lower() )
2013 			pNewUpper->Calc();
2014 
2015 		SwFtnBossFrm *pNewBoss = pNewUpper->FindFtnBossFrm();
2016 		sal_Bool bBossChg = pNewBoss != pOldBoss;
2017 		pNewBoss = pNewBoss->FindFtnBossFrm( sal_True );
2018 		pOldBoss = pOldBoss->FindFtnBossFrm( sal_True );
2019 		SwPageFrm* pNewPage = pOldPage;
2020 
2021 		// First, we move the footnotes.
2022 		sal_Bool bFtnMoved = sal_False;
2023 
2024         // --> FME 2004-07-15 #i26831#
2025         // If pSect has just been created, the printing area of pSect has
2026         // been calculated based on the first content of its follow.
2027         // In this case we prefer to call a SimpleFormat for this new
2028         // section after we inserted the contents. Otherwise the section
2029         // frame will invalidate its lowers, if its printing area changes
2030         // in SwSectionFrm::Format, which can cause loops.
2031         const bool bForceSimpleFormat = pSect && pSect->HasFollow() &&
2032                                        !pSect->ContainsAny();
2033         // <--
2034 
2035         if ( pNewBoss != pOldBoss )
2036 		{
2037 			pNewPage = pNewBoss->FindPageFrm();
2038 			bSamePage = pNewPage == pOldPage;
2039 			//Damit die Fussnoten nicht auf dumme Gedanken kommen
2040 			//setzen wir hier die Deadline.
2041             SWRECTFN( pOldBoss )
2042 			SwSaveFtnHeight aHeight( pOldBoss,
2043                 (pOldBoss->Frm().*fnRect->fnGetBottom)() );
2044 			SwCntntFrm* pStart = rThis.IsCntntFrm() ?
2045 				(SwCntntFrm*)&rThis : ((SwLayoutFrm&)rThis).ContainsCntnt();
2046 			ASSERT( pStart || ( rThis.IsTabFrm() && !((SwTabFrm&)rThis).Lower() ),
2047                     "MoveFwd: Missing Content" );
2048 			SwLayoutFrm* pBody = pStart ? ( pStart->IsTxtFrm() ?
2049 				(SwLayoutFrm*)((SwTxtFrm*)pStart)->FindBodyFrm() : 0 ) : 0;
2050 			if( pBody )
2051 				bFtnMoved = pBody->MoveLowerFtns( pStart, pOldBoss, pNewBoss,
2052 												  sal_False);
2053 		}
2054 		// Bei SectionFrms ist es moeglich, dass wir selbst durch pNewUpper->Calc()
2055 		// bewegt wurden, z. B. in den pNewUpper.
2056 		// MoveSubTree bzw. PasteTree ist auf so etwas nicht vorbereitet.
2057 		if( pNewUpper != rThis.GetUpper() )
2058 		{
2059             // --> FME 2004-04-19 #i27145#
2060             SwSectionFrm* pOldSct = 0;
2061             if ( rThis.GetUpper()->IsSctFrm() )
2062             {
2063                 pOldSct = static_cast<SwSectionFrm*>(rThis.GetUpper());
2064             }
2065             // <--
2066 
2067             MoveSubTree( pNewUpper, pNewUpper->Lower() );
2068 
2069             // --> FME 2004-04-19 #i27145#
2070             if ( pOldSct && pOldSct->GetSection() )
2071             {
2072                 // Prevent loops by setting the new height at
2073                 // the section frame if footnotes have been moved.
2074                 // Otherwise the call of SwLayNotify::~SwLayNotify() for
2075                 // the (invalid) section frame will invalidate the first
2076                 // lower of its follow, because it grows due to the removed
2077                 // footnotes.
2078                 // Note: If pOldSct has become empty during MoveSubTree, it
2079                 // has already been scheduled for removal. No SimpleFormat
2080                 // for these.
2081                 pOldSct->SimpleFormat();
2082             }
2083             // <--
2084 
2085             // --> FME 2004-07-15 #i26831#
2086             if ( bForceSimpleFormat )
2087             {
2088                 pSect->SimpleFormat();
2089             }
2090             // <--
2091 
2092             if ( bFtnMoved && !bSamePage )
2093 			{
2094 				pOldPage->UpdateFtnNum();
2095 				pNewPage->UpdateFtnNum();
2096 			}
2097 
2098 			if( bBossChg )
2099 			{
2100 				rThis.Prepare( PREP_BOSS_CHGD, 0, sal_False );
2101 				if( !bSamePage )
2102 				{
2103 					ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
2104 					if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
2105                         pSh->GetDoc()->SetNewFldLst(true);  //Wird von CalcLayout() hinterher erledigt!
2106 
2107                     pNewPage->InvalidateSpelling();
2108                     pNewPage->InvalidateSmartTags();    // SMARTTAGS
2109                     pNewPage->InvalidateAutoCompleteWords();
2110                     pNewPage->InvalidateWordCount();
2111 				}
2112 			}
2113 		}
2114         // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2115         const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
2116 
2117         if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
2118         {
2119             // --> OD 2009-12-31 #i106452#
2120             // check page description not only in situation with sections.
2121             if ( !bSamePage &&
2122                  ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() ||
2123                    pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) )
2124             {
2125                 SwFrm::CheckPageDescs( pNewPage, sal_False );
2126             }
2127             // <--
2128         }
2129 	}
2130 	return bSamePage;
2131 }
2132 
2133 
2134 /*************************************************************************
2135 |*
2136 |*	sal_Bool SwFlowFrm::MoveBwd()
2137 |*
2138 |*	Beschreibung		Returnwert sagt, ob der Frm die Seite wechseln soll.
2139 |*						Sollte von abgeleiteten Klassen gerufen werden.
2140 |* 						Das moven selbst muessen die abgeleiteten uebernehmen.
2141 |*	Ersterstellung		MA 05. Dec. 96
2142 |*	Letzte Aenderung	MA 05. Dec. 96
2143 |*
2144 |*************************************************************************/
2145 
2146 sal_Bool SwFlowFrm::MoveBwd( sal_Bool &rbReformat )
2147 {
2148 	SwFlowFrm::SetMoveBwdJump( sal_False );
2149 
2150 	SwFtnFrm* pFtn = rThis.FindFtnFrm();
2151 	if ( pFtn && pFtn->IsBackMoveLocked() )
2152 		return sal_False;
2153 
2154     // --> OD 2004-11-29 #115759# - text frames, which are directly inside
2155     // tables aren't allowed to move backward.
2156     if ( rThis.IsTxtFrm() && rThis.IsInTab() )
2157     {
2158         const SwLayoutFrm* pUpperFrm = rThis.GetUpper();
2159         while ( pUpperFrm )
2160         {
2161             if ( pUpperFrm->IsTabFrm() )
2162             {
2163                 return sal_False;
2164             }
2165             else if ( pUpperFrm->IsColumnFrm() && pUpperFrm->IsInSct() )
2166             {
2167                 break;
2168             }
2169             pUpperFrm = pUpperFrm->GetUpper();
2170         }
2171     }
2172     // <--
2173 
2174 	SwFtnBossFrm * pOldBoss = rThis.FindFtnBossFrm();
2175 	SwPageFrm * const pOldPage = pOldBoss->FindPageFrm();
2176 	SwLayoutFrm *pNewUpper = 0;
2177 	sal_Bool bCheckPageDescs = sal_False;
2178     bool bCheckPageDescOfNextPage = false;
2179 
2180 	if ( pFtn )
2181 	{
2182         //Wenn die Fussnote bereits auf der gleichen Seite/Spalte wie die Referenz
2183         //steht, ist nix mit zurueckfliessen. Die breaks brauche fuer die
2184         //Fussnoten nicht geprueft zu werden.
2185 
2186         // --> FME 2004-11-15 #i37084# FindLastCntnt does not necessarily
2187         // have to have a result != 0
2188         SwFrm* pRef = 0;
2189         const bool bEndnote = pFtn->GetAttr()->GetFtn().IsEndNote();
2190         if( bEndnote && pFtn->IsInSct() )
2191         {
2192             SwSectionFrm* pSect = pFtn->FindSctFrm();
2193             if( pSect->IsEndnAtEnd() )
2194                 pRef = pSect->FindLastCntnt( FINDMODE_LASTCNT );
2195         }
2196         if( !pRef )
2197             pRef = pFtn->GetRef();
2198         // <--
2199 
2200         ASSERT( pRef, "MoveBwd: Endnote for an empty section?" );
2201 
2202         if( !bEndnote )
2203 			pOldBoss = pOldBoss->FindFtnBossFrm( sal_True );
2204 		SwFtnBossFrm *pRefBoss = pRef->FindFtnBossFrm( !bEndnote );
2205         if ( pOldBoss != pRefBoss &&
2206              // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
2207              ( !bEndnote ||
2208                pRefBoss->IsBefore( pOldBoss ) )
2209            )
2210 			pNewUpper = rThis.GetLeaf( MAKEPAGE_FTN, sal_False );
2211 	}
2212 	else if ( IsPageBreak( sal_True ) )	//PageBreak zu beachten?
2213 	{
2214 		//Wenn auf der vorhergehenden Seite kein Frm im Body steht,
2215 		//so ist das Zurueckfliessen trotz Pagebreak sinnvoll
2216 		//(sonst: leere Seite).
2217 		//Natuerlich muessen Leereseiten geflissentlich uebersehen werden!
2218 		const SwFrm *pFlow = &rThis;
2219 		do
2220         {
2221             pFlow = pFlow->FindPrev();
2222         } while ( pFlow &&
2223                   ( pFlow->FindPageFrm() == pOldPage ||
2224                     !pFlow->IsInDocBody() ) );
2225 		if ( pFlow )
2226 		{
2227 			long nDiff = pOldPage->GetPhyPageNum() - pFlow->GetPhyPageNum();
2228 			if ( nDiff > 1 )
2229 			{
2230 				if ( ((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage() )
2231 					nDiff -= 1;
2232 				if ( nDiff > 1 )
2233 				{
2234 					pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2235                     // --> OD 2006-05-08 #i53139#
2236                     // Now <pNewUpper> is a previous layout frame, which contains
2237                     // content. But the new upper layout frame has to be the next one.
2238                     // Thus, hack for issue i14206 no longer needed, but fix for issue 114442
2239                     // --> OD 2006-05-17 #136024# - correct fix for i53139:
2240                     // Check for wrong page description before using next new upper.
2241                     // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2242                     // Check for correct type of new next upper layout frame
2243                     // --> OD 2006-06-08 #136538# - another correction of fix for i53139
2244                     // Assumption, that in all cases <pNewUpper> is a previous
2245                     // layout frame, which contains content, is wrong.
2246                     // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2247                     // Beside type check, check also, if proposed new next upper
2248                     // frame is inside the same frame types.
2249                     // --> OD 2007-01-10 #i73194# - and yet another correction
2250                     // of fix for i53139:
2251                     // Assure that the new next upper layout frame doesn't
2252                     // equal the current one.
2253                     // E.g.: content is on page 3, on page 2 is only a 'ghost'
2254                     // section and on page 1 is normal content. Method <FindPrev(..)>
2255                     // will find the last content of page 1, but <GetLeaf(..)>
2256                     // returns new upper on page 2.
2257                     if ( pNewUpper->Lower() )
2258                     {
2259                         SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, sal_True );
2260                         if ( pNewNextUpper &&
2261                              pNewNextUpper != rThis.GetUpper() &&
2262                              pNewNextUpper->GetType() == pNewUpper->GetType() &&
2263                              pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2264                              pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
2265                              pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2266                              pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2267                              !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
2268                         {
2269                             pNewUpper = pNewNextUpper;
2270                             bCheckPageDescOfNextPage = true;
2271                         }
2272                     }
2273                     // <--
2274 
2275                     bCheckPageDescs = sal_True;
2276 				}
2277 			}
2278 		}
2279 	}
2280 	else if ( IsColBreak( sal_True ) )
2281 	{
2282 		//Wenn in der vorhergehenden Spalte kein CntntFrm steht, so ist
2283 		//das Zurueckfliessen trotz ColumnBreak sinnvoll
2284 		//(sonst: leere Spalte).
2285 		if( rThis.IsInSct() )
2286 		{
2287 			pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2288 			if( pNewUpper && !SwFlowFrm::IsMoveBwdJump() &&
2289 				( pNewUpper->ContainsCntnt() ||
2290 				  ( ( !pNewUpper->IsColBodyFrm() ||
2291 					  !pNewUpper->GetUpper()->GetPrev() ) &&
2292 					!pNewUpper->FindSctFrm()->GetPrev() ) ) )
2293             {
2294 				pNewUpper = 0;
2295             }
2296             // --> OD 2006-05-08 #i53139#
2297             // --> OD 2006-09-11 #i69409# - check <pNewUpper>
2298             // --> OD 2006-11-02 #i71065# - check <SwFlowFrm::IsMoveBwdJump()>
2299             else if ( pNewUpper && !SwFlowFrm::IsMoveBwdJump() )
2300             // <--
2301             {
2302                 // Now <pNewUpper> is a previous layout frame, which
2303                 // contains content. But the new upper layout frame
2304                 // has to be the next one.
2305                 // --> OD 2006-05-17 #136024# - correct fix for i53139
2306                 // Check for wrong page description before using next new upper.
2307                 // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2308                 // Check for correct type of new next upper layout frame
2309                 // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2310                 // Beside type check, check also, if proposed new next upper
2311                 // frame is inside the same frame types.
2312                 SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NOSECTION, sal_True );
2313                 if ( pNewNextUpper &&
2314                      pNewNextUpper->GetType() == pNewUpper->GetType() &&
2315                      pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2316                      pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
2317                      pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2318                      pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2319                      !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
2320                 {
2321                     pNewUpper = pNewNextUpper;
2322                 }
2323             }
2324             // <--
2325 		}
2326 		else
2327 		{
2328 			const SwFrm *pCol = rThis.FindColFrm();
2329 			sal_Bool bGoOn = sal_True;
2330 			sal_Bool bJump = sal_False;
2331 			do
2332 			{
2333 				if ( pCol->GetPrev() )
2334 					pCol = pCol->GetPrev();
2335 				else
2336 				{
2337 					bGoOn = sal_False;
2338 					pCol = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2339 				}
2340 				if ( pCol )
2341 				{
2342 					// ColumnFrms jetzt mit BodyFrm
2343 					SwLayoutFrm* pColBody = pCol->IsColumnFrm() ?
2344 						(SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower() :
2345 						(SwLayoutFrm*)pCol;
2346 					if ( pColBody->ContainsCntnt() )
2347 					{
2348 						bGoOn = sal_False; // Hier gibt's Inhalt, wir akzeptieren diese
2349 						// nur, wenn GetLeaf() das MoveBwdJump-Flag gesetzt hat.
2350 						if( SwFlowFrm::IsMoveBwdJump() )
2351                         {
2352 							pNewUpper = pColBody;
2353                             // --> OD 2006-05-08 #i53139#
2354                             // Now <pNewUpper> is a previous layout frame, which
2355                             // contains content. But the new upper layout frame
2356                             // has to be the next one.
2357                             // --> OD 2006-05-17 #136024# - correct fix for i53139
2358                             // Check for wrong page description before using next new upper.
2359                             // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2360                             // Check for correct type of new next upper layout frame
2361                             // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2362                             // Beside type check, check also, if proposed new next upper
2363                             // frame is inside the same frame types.
2364                             // --> OD 2006-11-02 #i71065#
2365                             // Check that the proposed new next upper layout
2366                             // frame isn't the current one.
2367                             SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, sal_True );
2368                             if ( pNewNextUpper &&
2369                                  pNewNextUpper != rThis.GetUpper() &&
2370                                  pNewNextUpper->GetType() == pNewUpper->GetType() &&
2371                                  pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2372                                  pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
2373                                  pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2374                                  pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2375                                  !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
2376                             {
2377                                 pNewUpper = pNewNextUpper;
2378                             }
2379                             // <--
2380                         }
2381 					}
2382 					else
2383 					{
2384 						if( pNewUpper ) // Wir hatten schon eine leere Spalte, haben
2385 							bJump = sal_True;   // also eine uebersprungen
2386 						pNewUpper = pColBody;  // Diese leere Spalte kommt in Frage,
2387 										   	// trotzdem weitersuchen
2388 					}
2389 				}
2390 			} while( bGoOn );
2391 			if( bJump )
2392 				SwFlowFrm::SetMoveBwdJump( sal_True );
2393 		}
2394 	}
2395 	else //Keine Breaks also kann ich zurueckfliessen
2396 		pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2397 
2398     // --> OD 2004-06-23 #i27801# - no move backward of 'master' text frame,
2399     // if - due to its object positioning - it isn't allowed to be on the new page frame
2400     // --> OD 2005-03-07 #i44049# - add another condition for not moving backward:
2401     // If one of its objects has restarted the layout process, moving backward
2402     // isn't sensible either.
2403     // --> OD 2005-04-19 #i47697# - refine condition made for issue i44049:
2404     // - allow move backward as long as the anchored object is only temporarily
2405     //   positions considering its wrapping style.
2406     if ( pNewUpper &&
2407          rThis.IsTxtFrm() && !IsFollow() )
2408     {
2409         sal_uInt32 nToPageNum( 0L );
2410         const bool bMoveFwdByObjPos = SwLayouter::FrmMovedFwdByObjPos(
2411                                                 *(pOldPage->GetFmt()->GetDoc()),
2412                                                 static_cast<SwTxtFrm&>(rThis),
2413                                                 nToPageNum );
2414         if ( bMoveFwdByObjPos &&
2415              pNewUpper->FindPageFrm()->GetPhyPageNum() < nToPageNum )
2416         {
2417             pNewUpper = 0;
2418         }
2419         // --> OD 2005-03-07 #i44049# - check, if one of its anchored objects
2420         // has restarted the layout process.
2421         else if ( rThis.GetDrawObjs() )
2422         {
2423             sal_uInt32 i = 0;
2424             for ( ; i < rThis.GetDrawObjs()->Count(); ++i )
2425             {
2426                 SwAnchoredObject* pAnchoredObj = (*rThis.GetDrawObjs())[i];
2427                 // --> OD 2005-04-19 #i47697# - refine condition - see above
2428                 if ( pAnchoredObj->RestartLayoutProcess() &&
2429                      !pAnchoredObj->IsTmpConsiderWrapInfluence() )
2430                 // <--
2431                 {
2432                     pNewUpper = 0;
2433                     break;
2434                 }
2435             }
2436         }
2437         // <--
2438     }
2439     // <--
2440 
2441     //Fuer Follows ist das zurueckfliessen nur dann erlaubt wenn in der
2442 	//neuen Umgebung kein Nachbar existiert (denn dieses waere der Master).
2443 	//(6677)Wenn allerdings leere Blaetter uebersprungen wurden wird doch gemoved.
2444 	if ( pNewUpper && IsFollow() && pNewUpper->Lower() )
2445 	{
2446         // --> OD 2007-09-05 #i79774#, #b6596954#
2447         // neglect empty sections in proposed new upper frame
2448         bool bProposedNewUpperContainsOnlyEmptySections( true );
2449         {
2450             const SwFrm* pLower( pNewUpper->Lower() );
2451             while ( pLower )
2452             {
2453                 if ( pLower->IsSctFrm() &&
2454                      !dynamic_cast<const SwSectionFrm*>(pLower)->GetSection() )
2455                 {
2456                     pLower = pLower->GetNext();
2457                     continue;
2458                 }
2459                 else
2460                 {
2461                     bProposedNewUpperContainsOnlyEmptySections = false;
2462                     break;
2463                 }
2464             }
2465         }
2466         if ( !bProposedNewUpperContainsOnlyEmptySections )
2467         {
2468             if ( SwFlowFrm::IsMoveBwdJump() )
2469             {
2470                 //Nicht hinter den Master sondern in das naechstfolgende leere
2471                 //Blatt moven.
2472                 SwFrm *pFrm = pNewUpper->Lower();
2473                 while ( pFrm->GetNext() )
2474                     pFrm = pFrm->GetNext();
2475                 pNewUpper = pFrm->GetLeaf( MAKEPAGE_INSERT, sal_True );
2476                 if( pNewUpper == rThis.GetUpper() ) //Landen wir wieder an der gleichen Stelle?
2477                     pNewUpper = NULL;           //dann eruebrigt sich das Moven
2478             }
2479             else
2480                 pNewUpper = 0;
2481         }
2482         // <--
2483 	}
2484 	if ( pNewUpper && !ShouldBwdMoved( pNewUpper, sal_True, rbReformat ) )
2485 	{
2486 		if( !pNewUpper->Lower() )
2487 		{
2488 			if( pNewUpper->IsFtnContFrm() )
2489 			{
2490 				pNewUpper->Cut();
2491 				delete pNewUpper;
2492 			}
2493 			else
2494 			{
2495 				SwSectionFrm* pSectFrm = pNewUpper->FindSctFrm();
2496                 // --> OD 2006-01-04 #126020# - adjust check for empty section
2497                 // --> OD 2006-02-01 #130797# - correct fix #126020#
2498                 if ( pSectFrm && !pSectFrm->IsColLocked() &&
2499                      !pSectFrm->ContainsCntnt() && !pSectFrm->ContainsAny( true ) )
2500                 // <--
2501 				{
2502 					pSectFrm->DelEmpty( sal_True );
2503 					delete pSectFrm;
2504 					rThis.bValidPos = sal_True;
2505 				}
2506 			}
2507 		}
2508 		pNewUpper = 0;
2509 	}
2510 
2511     // OD 2004-05-26 #i21478# - don't move backward, if flow frame wants to
2512     // keep with next frame and next frame is locked.
2513     // --> OD 2004-12-08 #i38232# - If next frame is a table, do *not* check,
2514     // if it's locked.
2515     if ( pNewUpper && !IsFollow() &&
2516          rThis.GetAttrSet()->GetKeep().GetValue() && rThis.GetIndNext() )
2517     {
2518         SwFrm* pIndNext = rThis.GetIndNext();
2519         // --> OD 2004-12-08 #i38232#
2520         if ( !pIndNext->IsTabFrm() )
2521         {
2522             // get first content of section, while empty sections are skipped
2523             while ( pIndNext && pIndNext->IsSctFrm() )
2524             {
2525                 if( static_cast<SwSectionFrm*>(pIndNext)->GetSection() )
2526                 {
2527                     SwFrm* pTmp = static_cast<SwSectionFrm*>(pIndNext)->ContainsAny();
2528                     if ( pTmp )
2529                     {
2530                         pIndNext = pTmp;
2531                         break;
2532                     }
2533                 }
2534                 pIndNext = pIndNext->GetIndNext();
2535             }
2536             ASSERT( !pIndNext || pIndNext->ISA(SwTxtFrm),
2537                     "<SwFlowFrm::MovedBwd(..)> - incorrect next found." );
2538             if ( pIndNext && pIndNext->IsFlowFrm() &&
2539                  SwFlowFrm::CastFlowFrm(pIndNext)->IsJoinLocked() )
2540             {
2541                 pNewUpper = 0L;
2542             }
2543         }
2544         // <--
2545     }
2546 
2547     // --> OD 2006-05-10 #i65250#
2548     // layout loop control for flowing content again and again moving
2549     // backward under the same layout condition.
2550     if ( pNewUpper && !IsFollow() &&
2551          pNewUpper != rThis.GetUpper() &&
2552          SwLayouter::MoveBwdSuppressed( *(pOldPage->GetFmt()->GetDoc()),
2553                                         *this, *pNewUpper ) )
2554     {
2555         SwLayoutFrm* pNextNewUpper = pNewUpper->GetLeaf(
2556                                     ( !rThis.IsSctFrm() && rThis.IsInSct() )
2557                                     ? MAKEPAGE_NOSECTION
2558                                     : MAKEPAGE_NONE,
2559                                     sal_True );
2560         // --> OD 2007-01-10 #i73194# - make code robust
2561         ASSERT( pNextNewUpper, "<SwFlowFrm::MoveBwd(..)> - missing next new upper" );
2562         if ( pNextNewUpper &&
2563              ( pNextNewUpper == rThis.GetUpper() ||
2564                pNextNewUpper->GetType() != rThis.GetUpper()->GetType() ) )
2565         // <--
2566         {
2567             pNewUpper = 0L;
2568 #if OSL_DEBUG_LEVEL > 1
2569             ASSERT( false,
2570                     "<SwFlowFrm::MoveBwd(..)> - layout loop control for layout action <Move Backward> applied!" );
2571 #endif
2572         }
2573     }
2574     // <--
2575 
2576     ASSERT( pNewUpper != rThis.GetUpper(),
2577             "<SwFlowFrm::MoveBwd(..)> - moving backward to the current upper frame!? -> Please inform OD." );
2578 	if ( pNewUpper )
2579 	{
2580 		PROTOCOL_ENTER( &rThis, PROT_MOVE_BWD, 0, 0 );
2581 		if ( pNewUpper->IsFtnContFrm() )
2582 		{
2583 			//Kann sein, dass ich einen Container bekam.
2584 			SwFtnFrm *pOld = rThis.FindFtnFrm();
2585 			SwFtnFrm *pNew = new SwFtnFrm( pOld->GetFmt(), pOld,
2586 										   pOld->GetRef(), pOld->GetAttr() );
2587 			if ( pOld->GetMaster() )
2588 			{
2589 				pNew->SetMaster( pOld->GetMaster() );
2590 				pOld->GetMaster()->SetFollow( pNew );
2591 			}
2592 			pNew->SetFollow( pOld );
2593 			pOld->SetMaster( pNew );
2594 			pNew->Paste( pNewUpper );
2595 			pNewUpper = pNew;
2596 		}
2597 		if( pNewUpper->IsFtnFrm() && rThis.IsInSct() )
2598 		{
2599 			SwSectionFrm* pSct = rThis.FindSctFrm();
2600 			//Wenn wir in einem Bereich in einer Fussnote stecken, muss im
2601 			//neuen Upper ggf. ein SwSectionFrm angelegt werden
2602 			if( pSct->IsInFtn() )
2603 			{
2604 				SwFrm* pTmp = pNewUpper->Lower();
2605 				if( pTmp )
2606 				{
2607 					while( pTmp->GetNext() )
2608 						pTmp = pTmp->GetNext();
2609 					if( !pTmp->IsSctFrm() ||
2610 						((SwSectionFrm*)pTmp)->GetFollow() != pSct )
2611 						pTmp = NULL;
2612 				}
2613 				if( pTmp )
2614 					pNewUpper = (SwSectionFrm*)pTmp;
2615 				else
2616 				{
2617                     pSct = new SwSectionFrm( *pSct, sal_True );
2618 					pSct->Paste( pNewUpper );
2619                     pSct->Init();
2620 					pNewUpper = pSct;
2621 					pSct->SimpleFormat();
2622 				}
2623 			}
2624 		}
2625 		sal_Bool bUnlock = sal_False;
2626         sal_Bool bFollow = sal_False;
2627 		//Section locken, sonst kann sie bei Fluss des einzigen Cntnt etwa
2628 		//von zweiter in die erste Spalte zerstoert werden.
2629 		SwSectionFrm* pSect = pNewUpper->FindSctFrm();
2630 		if( pSect )
2631 		{
2632 			bUnlock = !pSect->IsColLocked();
2633 			pSect->ColLock();
2634 			bFollow = pSect->HasFollow();
2635 		}
2636 		pNewUpper->Calc();
2637 		rThis.Cut();
2638         // --> OD 2005-02-23 #b6229852#
2639         // optimization: format section, if its size is invalidated and if it's
2640         // the new parent of moved backward frame.
2641         bool bFormatSect( false );
2642         // <--
2643         if( bUnlock )
2644 		{
2645             pSect->ColUnlock();
2646             if( pSect->HasFollow() != bFollow )
2647             {
2648 				pSect->InvalidateSize();
2649                 // --> OD 2005-02-23 #b6229852# - optimization
2650                 if ( pSect == pNewUpper )
2651                     bFormatSect = true;
2652                 // <--
2653             }
2654 		}
2655 
2656 		rThis.Paste( pNewUpper );
2657         // --> OD 2005-02-23 #b6229852# - optimization
2658         if ( bFormatSect )
2659             pSect->Calc();
2660         // <--
2661 
2662         SwPageFrm *pNewPage = rThis.FindPageFrm();
2663 		if( pNewPage != pOldPage )
2664 		{
2665 			rThis.Prepare( PREP_BOSS_CHGD, (const void*)pOldPage, sal_False );
2666 			ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
2667 			if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
2668                 pSh->GetDoc()->SetNewFldLst(true);  //Wird von CalcLayout() hinterher eledigt!
2669 
2670             pNewPage->InvalidateSpelling();
2671             pNewPage->InvalidateSmartTags();    // SMARTTAGS
2672 			pNewPage->InvalidateAutoCompleteWords();
2673             pNewPage->InvalidateWordCount();
2674 
2675             // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2676             if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
2677             {
2678                 if ( bCheckPageDescs && pNewPage->GetNext() )
2679                 {
2680                     SwPageFrm* pStartPage = bCheckPageDescOfNextPage ?
2681                                             pNewPage :
2682                                             (SwPageFrm*)pNewPage->GetNext();
2683                     SwFrm::CheckPageDescs( pStartPage, sal_False);
2684                 }
2685                 else if ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() )
2686                 {
2687                     //Erste Seite wird etwa durch Ausblenden eines Bereiches leer
2688                     SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage, sal_False);
2689                 }
2690             }
2691 		}
2692 	}
2693 	return pNewUpper != 0;
2694 }
2695 
2696 /*************************************************************************
2697 |*
2698 |*	SwFlowFrm::CastFlowFrm
2699 |*
2700 |*	Ersterstellung		MA 03. May. 95
2701 |*	Letzte Aenderung	AMA 02. Dec. 97
2702 |*
2703 |*************************************************************************/
2704 
2705 SwFlowFrm *SwFlowFrm::CastFlowFrm( SwFrm *pFrm )
2706 {
2707 	if ( pFrm->IsCntntFrm() )
2708 		return (SwCntntFrm*)pFrm;
2709 	if ( pFrm->IsTabFrm() )
2710 		return (SwTabFrm*)pFrm;
2711 	if ( pFrm->IsSctFrm() )
2712 		return (SwSectionFrm*)pFrm;
2713 	return 0;
2714 }
2715 
2716 const SwFlowFrm *SwFlowFrm::CastFlowFrm( const SwFrm *pFrm )
2717 {
2718 	if ( pFrm->IsCntntFrm() )
2719 		return (SwCntntFrm*)pFrm;
2720 	if ( pFrm->IsTabFrm() )
2721 		return (SwTabFrm*)pFrm;
2722 	if ( pFrm->IsSctFrm() )
2723 		return (SwSectionFrm*)pFrm;
2724 	return 0;
2725 }
2726