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