xref: /aoo41x/main/sw/source/core/layout/frmtool.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 #include <hintids.hxx>
31 #include <tools/bigint.hxx>
32 #include <svx/svdmodel.hxx>
33 #include <svx/svdpage.hxx>
34 #include <editeng/brshitem.hxx>
35 #include <editeng/keepitem.hxx>
36 #include <editeng/shaditem.hxx>
37 #include <editeng/ulspitem.hxx>
38 #include <editeng/lrspitem.hxx>
39 #include <editeng/boxitem.hxx>
40 #include <sfx2/printer.hxx>
41 #include <editeng/lspcitem.hxx>
42 
43 #include <fmtornt.hxx>
44 #include <fmtanchr.hxx>
45 #include <fmthdft.hxx>
46 #include <fmtcntnt.hxx>
47 #include <fmtfsize.hxx>
48 #include <fmtsrnd.hxx>
49 #include <docary.hxx>
50 #include <lineinfo.hxx>
51 #include <swmodule.hxx>
52 #include "pagefrm.hxx"
53 #include "colfrm.hxx"
54 #include "doc.hxx"
55 #include "fesh.hxx"
56 #include "viewimp.hxx"
57 #include "viewopt.hxx"
58 #include "pam.hxx"
59 #include "dflyobj.hxx"
60 #include "dcontact.hxx"
61 #include "frmtool.hxx"
62 #include "docsh.hxx"
63 #include "tabfrm.hxx"
64 #include "rowfrm.hxx"
65 #include "ftnfrm.hxx"
66 #include "txtfrm.hxx"
67 #include "notxtfrm.hxx"
68 #include "flyfrms.hxx"
69 #include "layact.hxx"
70 #include "pagedesc.hxx"
71 #include "section.hxx"
72 #include "sectfrm.hxx"
73 #include "node2lay.hxx"
74 #include "ndole.hxx"
75 #include "ndtxt.hxx"
76 #include "swtable.hxx"
77 #include "hints.hxx"
78 #include <layhelp.hxx>
79 #include <laycache.hxx>
80 #include <rootfrm.hxx>
81 #include "mdiexp.hxx"
82 #include "statstr.hrc"
83 #include <paratr.hxx>
84 #include <sortedobjs.hxx>
85 #include <objectformatter.hxx>
86 #include <switerator.hxx>
87 
88 // ftnfrm.cxx:
89 void lcl_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );
90 
91 using namespace ::com::sun::star;
92 
93 
94 sal_Bool bObjsDirect = sal_True;
95 sal_Bool bDontCreateObjects = sal_False;
96 sal_Bool bSetCompletePaintOnInvalidate = sal_False;
97 
98 sal_uInt8 StackHack::nCnt = 0;
99 sal_Bool StackHack::bLocked = sal_False;
100 
101 
102 
103 /*************************************************************************/
104 
105 SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
106 	pFrm( pF ),
107 	aFrm( pF->Frm() ),
108 	aPrt( pF->Prt() ),
109     bInvaKeep( sal_False ),
110     bValidSize( pF->GetValidSizeFlag() ),
111     mbFrmDeleted( false )     // #i49383#
112 {
113     if ( pF->IsTxtFrm() )
114     {
115         mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True );
116         mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False );
117     }
118     else
119     {
120         mnFlyAnchorOfst = 0;
121         mnFlyAnchorOfstNoWrap = 0;
122     }
123 
124 	bHadFollow = pF->IsCntntFrm() ?
125 					(((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
126 					sal_False;
127 }
128 
129 /*************************************************************************/
130 
131 SwFrmNotify::~SwFrmNotify()
132 {
133     // #i49383#
134     if ( mbFrmDeleted )
135     {
136         return;
137     }
138 
139     SWRECTFN( pFrm )
140     const sal_Bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
141     const sal_Bool bChgWidth =
142             (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
143     const sal_Bool bChgHeight =
144             (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
145     const sal_Bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
146        ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) ||
147          ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) );
148 
149 	if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
150 	{
151 		SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
152 
153 		if ( !pFlow->IsFollow() )
154 		{
155 			if ( !pFrm->GetIndPrev() )
156 			{
157 				if ( bInvaKeep )
158 				{
159                     SwFrm *pPre = pFrm->FindPrev();
160                     if ( pPre && pPre->IsFlowFrm() )
161                     {
162                         // 1. pPre wants to keep with me:
163                         bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
164 
165                         // 2. pPre is a table and the last row wants to keep with me:
166                         if ( !bInvalidPrePos && pPre->IsTabFrm() )
167                         {
168                             SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
169                             if ( pPreTab->GetFmt()->GetDoc()->get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
170                             {
171                                 SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
172                                 if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
173                                     bInvalidPrePos = true;
174                             }
175                         }
176 
177                         if ( bInvalidPrePos )
178                             pPre->InvalidatePos();
179                     }
180 				}
181 			}
182             else if ( !pFlow->HasFollow() )
183             {
184                 long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
185                 long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
186                 if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
187                     pFlow->CheckKeep();
188             }
189 		}
190 	}
191 
192 	if ( bAbsP )
193 	{
194 		pFrm->SetCompletePaint();
195 
196 		SwFrm* pNxt = pFrm->GetIndNext();
197         // #121888# - skip empty section frames
198         while ( pNxt &&
199                 pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
200         {
201             pNxt = pNxt->GetIndNext();
202         }
203 
204 		if ( pNxt )
205 			pNxt->InvalidatePos();
206 		else
207 		{
208             // #104100# - correct condition for setting retouche
209             // flag for vertical layout.
210             if( pFrm->IsRetoucheFrm() &&
211                 (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
212             {
213 				pFrm->SetRetouche();
214             }
215 
216             // A fresh follow frame does not have to be invalidated, because
217             // it is already formatted:
218             if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
219             {
220                 if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
221                     pFrm->InvalidateNextPos();
222             }
223         }
224 	}
225 
226 	//Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her.
227     const sal_Bool bPrtWidth =
228             (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
229     const sal_Bool bPrtHeight =
230             (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
231     if ( bPrtWidth || bPrtHeight )
232 	{
233 		const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
234 		if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
235 			pFrm->SetCompletePaint();
236 	}
237     else
238     {
239         // #97597# - consider case that *only* margins between
240         // frame and printing area has changed. Then, frame has to be repainted,
241         // in order to force paint of the margin areas.
242         if ( !bAbsP && (bChgWidth || bChgHeight) )
243         {
244             pFrm->SetCompletePaint();
245         }
246     }
247 
248 	const sal_Bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
249     if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
250          bPrtWidth || bPrtHeight || bChgFlyBasePos )
251 	{
252 		if( pFrm->IsAccessibleFrm() )
253 		{
254 			SwRootFrm *pRootFrm = pFrm->getRootFrm();
255 			if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
256 				pRootFrm->GetCurrShell() )
257 			{
258 				pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
259 			}
260 		}
261 
262         // Notification of anchored objects
263         if ( pFrm->GetDrawObjs() )
264         {
265             const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
266             SwPageFrm* pPageFrm = 0;
267             for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
268             {
269                 // OD 2004-03-31 #i26791# - no general distinction between
270                 // Writer fly frames and drawing objects
271                 bool bNotify = false;
272                 bool bNotifySize = false;
273                 SwAnchoredObject* pObj = rObjs[i];
274                 SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
275                 // --> OD 2004-12-08 #115759#
276                 const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
277                 if ( !bAnchoredAsChar )
278                 // <--
279                 {
280                     // Notify object, which aren't anchored as-character:
281 
282                     // always notify objects, if frame position has changed
283                     // or if the object is to-page|to-fly anchored.
284                     if ( bAbsP ||
285                          pContact->ObjAnchoredAtPage() ||
286                          pContact->ObjAnchoredAtFly() )
287                     {
288                         bNotify = true;
289 
290                         // assure that to-fly anchored Writer fly frames are
291                         // registered at the correct page frame, if frame
292                         // position has changed.
293                         if ( bAbsP && pContact->ObjAnchoredAtFly() &&
294                              pObj->ISA(SwFlyFrm) )
295                         {
296                             // determine to-fly anchored Writer fly frame
297                             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
298                             // determine page frame of to-fly anchored
299                             // Writer fly frame
300                             SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
301                             // determine page frame, if needed.
302                             if ( !pPageFrm )
303                             {
304                                 pPageFrm = pFrm->FindPageFrm();
305                             }
306                             if ( pPageFrm != pFlyPageFrm )
307                             {
308                                 ASSERT( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
309                                 if( pFlyPageFrm )
310                                     pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
311                                 else
312                                     pPageFrm->AppendFlyToPage( pFlyFrm );
313                             }
314                         }
315                     }
316                     // otherwise the objects are notified in dependence to
317                     // its positioning and alignment
318                     else
319                     {
320                         const SwFmtVertOrient& rVert =
321                                         pContact->GetFmt()->GetVertOrient();
322                         if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
323                                rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
324                                rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
325                              ( bChgHeight || bPrtHeight ) )
326                         {
327                             bNotify = true;
328                         }
329                         if ( !bNotify )
330                         {
331                             const SwFmtHoriOrient& rHori =
332                                         pContact->GetFmt()->GetHoriOrient();
333                             if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
334                                    rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
335                                    rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
336                                  ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
337                             {
338                                 bNotify = true;
339                             }
340                         }
341                     }
342                 }
343                 else if ( bPrtWidth )
344                 {
345                     // Notify as-character anchored objects, if printing area
346                     // width has changed.
347                     bNotify = true;
348                     bNotifySize = true;
349                 }
350 
351                 // perform notification via the corresponding invalidations
352                 if ( bNotify )
353                 {
354                     if ( pObj->ISA(SwFlyFrm) )
355                     {
356                         SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
357                         if ( bNotifySize )
358                             pFlyFrm->_InvalidateSize();
359                         // --> OD 2004-12-08 #115759# - no invalidation of
360                         // position for as-character anchored objects.
361                         if ( !bAnchoredAsChar )
362                         {
363                             pFlyFrm->_InvalidatePos();
364                         }
365                         // <--
366                         pFlyFrm->_Invalidate();
367                     }
368                     else if ( pObj->ISA(SwAnchoredDrawObject) )
369                     {
370                         // --> OD 2004-12-08 #115759# - no invalidation of
371                         // position for as-character anchored objects.
372                         if ( !bAnchoredAsChar )
373                         {
374                             pObj->InvalidateObjPos();
375                         }
376                         // <--
377                     }
378                     else
379                     {
380                         ASSERT( false,
381                                 "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
382                     }
383                 }
384             }
385         }
386 	}
387 	else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
388 	{
389 		SwRootFrm *pRootFrm = pFrm->getRootFrm();
390 		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
391 			pRootFrm->GetCurrShell() )
392 		{
393 			pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
394 		}
395 	}
396 
397     // #i9046# Automatic frame width
398     SwFlyFrm* pFly = 0;
399     // --> FME 2004-10-21 #i35879# Do not trust the inf flags. pFrm does not
400     // necessarily have to have an upper!
401     if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
402     // <--
403     {
404         // --> OD 2006-05-08 #i61999#
405         // no invalidation of columned Writer fly frames, because automatic
406         // width doesn't make sense for such Writer fly frames.
407         if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
408         {
409             const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
410 
411             // This could be optimized. Basically the fly frame only has to
412             // be invalidated, if the first line of pFrm (if pFrm is a content
413             // frame, for other frame types its the print area) has changed its
414             // size and pFrm was responsible for the current width of pFly. On
415             // the other hand, this is only rarely used and re-calculation of
416             // the fly frame does not cause too much trouble. So we keep it this
417             // way:
418             if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
419             {
420                 // --> OD 2005-07-29 #i50668#, #i50998# - invalidation of position
421                 // of as-character anchored fly frames not needed and can cause
422                 // layout loops
423                 if ( !pFly->ISA(SwFlyInCntFrm) )
424                 {
425                     pFly->InvalidatePos();
426                 }
427                 // <--
428                 pFly->InvalidateSize();
429             }
430         }
431         // <--
432     }
433 }
434 
435 /*************************************************************************/
436 
437 SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
438 	SwFrmNotify( pLayFrm ),
439     bLowersComplete( sal_False )
440 {
441 }
442 
443 /*************************************************************************/
444 
445 // OD 2004-05-11 #i28701# - local method to invalidate the position of all
446 // frames inclusive its floating screen objects, which are lowers of the given
447 // layout frame
448 void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
449 {
450     if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
451     {
452         _rLayoutFrm.InvalidateObjs( true, false );
453     }
454 
455     SwFrm* pLowerFrm = _rLayoutFrm.Lower();
456     while ( pLowerFrm )
457     {
458         pLowerFrm->InvalidatePos();
459         if ( pLowerFrm->IsTxtFrm() )
460         {
461             static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
462         }
463         else if ( pLowerFrm->IsTabFrm() )
464         {
465             pLowerFrm->InvalidatePrt();
466         }
467 
468         pLowerFrm->InvalidateObjs( true, false );
469 
470         pLowerFrm = pLowerFrm->GetNext();
471     };
472 }
473 
474 SwLayNotify::~SwLayNotify()
475 {
476     // --> OD 2005-07-29 #i49383#
477     if ( mbFrmDeleted )
478     {
479         return;
480     }
481     // <--
482 
483 	SwLayoutFrm *pLay = GetLay();
484     SWRECTFN( pLay )
485 	sal_Bool bNotify = sal_False;
486 	if ( pLay->Prt().SSize() != aPrt.SSize() )
487 	{
488 		if ( !IsLowersComplete() )
489 		{
490 			sal_Bool bInvaPercent;
491 
492 			if ( pLay->IsRowFrm() )
493 			{
494 				bInvaPercent = sal_True;
495                 long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
496                 if( nNew != (aPrt.*fnRect->fnGetHeight)() )
497                      ((SwRowFrm*)pLay)->AdjustCells( nNew, sal_True);
498                 if( (pLay->Prt().*fnRect->fnGetWidth)()
499                     != (aPrt.*fnRect->fnGetWidth)() )
500 					 ((SwRowFrm*)pLay)->AdjustCells( 0, sal_False );
501 			}
502 			else
503 			{
504 				//Proportionale Anpassung der innenliegenden.
505 				//1. Wenn der Formatierte kein Fly ist
506 				//2. Wenn er keine Spalten enthaelt
507 				//3. Wenn der Fly eine feste Hoehe hat und die Spalten in der
508 				//	 Hoehe danebenliegen.
509 				//4. niemals bei SectionFrms.
510 				sal_Bool bLow;
511 				if( pLay->IsFlyFrm() )
512 				{
513 					if ( pLay->Lower() )
514 					{
515 						bLow = !pLay->Lower()->IsColumnFrm() ||
516                             (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
517                              != (pLay->Prt().*fnRect->fnGetHeight)();
518 					}
519 					else
520 						bLow = sal_False;
521 				}
522 				else if( pLay->IsSctFrm() )
523 				{
524 					if ( pLay->Lower() )
525 					{
526 						if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
527 							bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
528 						else
529 							bLow = pLay->Prt().Width() != aPrt.Width();
530 					}
531 					else
532 						bLow = sal_False;
533 				}
534                 else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
535                     bLow = pLay->Prt().Width() != aPrt.Width();
536                 else
537 					bLow = sal_True;
538 				bInvaPercent = bLow;
539 				if ( bLow )
540 				{
541                     pLay->ChgLowersProp( aPrt.SSize() );
542                 }
543 				//Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
544 				//Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
545 				//mithin muss also der 'moeglicherweise passende' Invalidiert werden.
546 				//Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
547 				//Uppers um eine Moveable-Section handelt.
548 				//Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
549 				//geworden ist.
550 				if ( (pLay->Prt().Height() > aPrt.Height() ||
551 					  pLay->Prt().Width()  > aPrt.Width()) &&
552 					 (pLay->IsMoveable() || pLay->IsFlyFrm()) )
553 				{
554                     SwFrm *pTmpFrm = pLay->Lower();
555                     if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
556 					{
557                         while ( pTmpFrm->GetNext() )
558                             pTmpFrm = pTmpFrm->GetNext();
559                         pTmpFrm->InvalidateNextPos();
560 					}
561 				}
562 			}
563 			bNotify = sal_True;
564 			//TEUER!! aber wie macht man es geschickter?
565 			if( bInvaPercent )
566                 pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
567 		}
568 		if ( pLay->IsTabFrm() )
569 			//Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird.
570 			((SwTabFrm*)pLay)->SetComplete();
571         else
572         {
573             const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
574             if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
575 				  !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
576 			//Damit die untergeordneten sauber retouchiert werden.
577 			//Problembsp: Flys an den Henkeln packen und verkleinern.
578 			//Nicht fuer Body und Page, sonst flackerts beim HTML-Laden.
579 			pLay->SetCompletePaint();
580         }
581 	}
582 	//Lower benachrichtigen wenn sich die Position veraendert hat.
583     const sal_Bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
584     const sal_Bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
585 	const sal_Bool bSize = pLay->Frm().SSize() != aFrm.SSize();
586 
587 	if ( bPos && pLay->Lower() && !IsLowersComplete() )
588 		pLay->Lower()->InvalidatePos();
589 
590     if ( bPrtPos )
591 		pLay->SetCompletePaint();
592 
593 	//Nachfolger benachrichtigen wenn sich die SSize geaendert hat.
594 	if ( bSize )
595 	{
596 		if( pLay->GetNext() )
597 		{
598 			if ( pLay->GetNext()->IsLayoutFrm() )
599 				pLay->GetNext()->_InvalidatePos();
600 			else
601 				pLay->GetNext()->InvalidatePos();
602 		}
603 		else if( pLay->IsSctFrm() )
604 			pLay->InvalidateNextPos();
605 	}
606 	if ( !IsLowersComplete() &&
607 		 !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
608 			pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
609 		 (bPos || bNotify) && !(pLay->GetType() & 0x1823) )  //Tab, Row, FtnCont, Root, Page
610 	{
611         // --> OD 2005-03-11 #i44016# - force unlock of position of lower objects.
612         // --> OD 2005-03-30 #i43913# - no unlock of position of objects,
613         // if <pLay> is a cell frame, and its table frame resp. its parent table
614         // frame is locked.
615         // --> OD 2005-04-15 #i47458# - force unlock of position of lower objects,
616         // only if position of layout frame has changed.
617         bool bUnlockPosOfObjs( bPos );
618         if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
619         {
620             SwTabFrm* pTabFrm( pLay->FindTabFrm() );
621             if ( pTabFrm &&
622                  ( pTabFrm->IsJoinLocked() ||
623                    ( pTabFrm->IsFollow() &&
624                      pTabFrm->FindMaster()->IsJoinLocked() ) ) )
625             {
626                 bUnlockPosOfObjs = false;
627             }
628         }
629         // --> OD 2005-05-18 #i49383# - check for footnote frame, if unlock
630         // of position of lower objects is allowed.
631         else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
632         {
633             bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
634         }
635         // <--
636         // --> OD 2005-07-29 #i51303# - no unlock of object positions for sections
637         else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
638         {
639             bUnlockPosOfObjs = false;
640         }
641         // <--
642         pLay->NotifyLowerObjs( bUnlockPosOfObjs );
643         // <--
644 	}
645 	if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
646 	{
647         // OD 2004-05-11 #i28701#
648         ::lcl_InvalidatePosOfLowers( *pLay );
649 	}
650     if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
651           && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
652         ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
653 }
654 
655 /*************************************************************************/
656 
657 SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
658 	SwLayNotify( pFlyFrm ),
659     // --> OD 2004-11-24 #115759# - keep correct page frame - the page frame
660     // the Writer fly frame is currently registered at.
661     pOldPage( pFlyFrm->GetPageFrm() ),
662     // <--
663     aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
664 {
665 }
666 
667 /*************************************************************************/
668 
669 SwFlyNotify::~SwFlyNotify()
670 {
671     // --> OD 2005-07-29 #i49383#
672     if ( mbFrmDeleted )
673     {
674         return;
675     }
676     // <--
677 
678 	SwFlyFrm *pFly = GetFly();
679 	if ( pFly->IsNotifyBack() )
680 	{
681 		ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
682 		SwViewImp *pImp = pSh ? pSh->Imp() : 0;
683 		if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
684 		{
685 			//Wenn in der LayAction das IsAgain gesetzt ist kann es sein,
686 			//dass die alte Seite inzwischen vernichtet wurde!
687             ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
688             // --> OD 2004-10-20 #i35640# - additional notify anchor text frame,
689             // if Writer fly frame has changed its page
690             if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
691                  pFly->GetPageFrm() != pOldPage )
692             {
693                 pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
694             }
695             // <--
696 		}
697 		pFly->ResetNotifyBack();
698 	}
699 
700 	//Haben sich Groesse oder Position geaendert, so sollte die View
701 	//das wissen.
702     SWRECTFN( pFly )
703     const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
704     const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
705     const bool bPrtChgd = aPrt != pFly->Prt();
706     if ( bPosChgd || bFrmChgd || bPrtChgd )
707 	{
708 		pFly->NotifyDrawObj();
709 	}
710 	if ( bPosChgd && aFrm.Pos().X() != WEIT_WECH )
711 	{
712         // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
713         // reason: New positioning and alignment (e.g. to-paragraph anchored,
714         // but aligned at page) are introduced.
715         // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
716         // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
717 
718 		if ( pFly->IsFlyAtCntFrm() )
719 		{
720             SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
721 			if ( pNxt )
722             {
723 				pNxt->InvalidatePos();
724             }
725 		}
726 
727         // --> OD 2004-11-05 #i26945# - notify anchor.
728         // Needed for negative positioned Writer fly frames
729         if ( pFly->GetAnchorFrm()->IsTxtFrm() )
730         {
731             pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
732         }
733         // <--
734 	}
735 
736     // OD 2004-05-13 #i28701#
737     // --> OD 2005-03-21 #i45180# - no adjustment of layout process flags and
738     // further notifications/invalidations, if format is called by grow/shrink
739     if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
740          ( !pFly->ISA(SwFlyFreeFrm) ||
741            !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
742     // <--
743     {
744         // --> OD 2005-09-05 #i54138# - suppress restart of the layout process
745         // on changed frame height.
746         // Note: It doesn't seem to be necessary and can cause layout loops.
747         if ( bPosChgd )
748         // <--
749         {
750             // indicate a restart of the layout process
751             pFly->SetRestartLayoutProcess( true );
752         }
753         else
754         {
755             // lock position
756             pFly->LockPosition();
757 
758             if ( !pFly->ConsiderForTextWrap() )
759             {
760                 // indicate that object has to be considered for text wrap
761                 pFly->SetConsiderForTextWrap( true );
762                 // invalidate 'background' in order to allow its 'background'
763                 // to wrap around it.
764                 pFly->NotifyBackground( pFly->GetPageFrm(),
765                                         pFly->GetObjRectWithSpaces(),
766                                         PREP_FLY_ARRIVE );
767                 // invalidate position of anchor frame in order to force
768                 // a re-format of the anchor frame, which also causes a
769                 // re-format of the invalid previous frames of the anchor frame.
770                 pFly->AnchorFrm()->InvalidatePos();
771             }
772         }
773     }
774 }
775 
776 /*************************************************************************/
777 
778 SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
779     SwFrmNotify( pCntntFrm ),
780     // OD 08.01.2004 #i11859#
781     mbChkHeightOfLastLine( false ),
782     mnHeightOfLastLine( 0L ),
783     // OD 2004-02-26 #i25029#
784     mbInvalidatePrevPrtArea( false ),
785     mbBordersJoinedWithPrev( false )
786 {
787     // OD 08.01.2004 #i11859#
788     if ( pCntntFrm->IsTxtFrm() )
789     {
790         SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
791         if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
792         {
793             const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
794             const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
795             if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
796             {
797                 mbChkHeightOfLastLine = true;
798                 mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
799             }
800         }
801     }
802 }
803 
804 /*************************************************************************/
805 
806 SwCntntNotify::~SwCntntNotify()
807 {
808     // --> OD 2005-07-29 #i49383#
809     if ( mbFrmDeleted )
810     {
811         return;
812     }
813     // <--
814 
815 	SwCntntFrm *pCnt = GetCnt();
816 	if ( bSetCompletePaintOnInvalidate )
817 		pCnt->SetCompletePaint();
818 
819     SWRECTFN( pCnt )
820     if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
821 							 pCnt->Frm().SSize() != aFrm.SSize()))
822 	{
823 		SwLayoutFrm* pCell = pCnt->GetUpper();
824 		while( !pCell->IsCellFrm() && pCell->GetUpper() )
825 			pCell = pCell->GetUpper();
826 		ASSERT( pCell->IsCellFrm(), "Where's my cell?" );
827         if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
828 			pCell->InvalidatePrt();	//fuer vertikale Ausrichtung.
829 	}
830 
831     // OD 2004-02-26 #i25029#
832     if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
833          pCnt->IsTxtFrm() &&
834          !pCnt->IsFollow() && !pCnt->GetIndPrev() )
835     {
836         // determine previous frame
837         SwFrm* pPrevFrm = pCnt->FindPrev();
838         // skip empty section frames and hidden text frames
839         {
840             while ( pPrevFrm &&
841                     ( ( pPrevFrm->IsSctFrm() &&
842                         !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
843                       ( pPrevFrm->IsTxtFrm() &&
844                         static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
845             {
846                 pPrevFrm = pPrevFrm->FindPrev();
847             }
848         }
849 
850         // Invalidate printing area of found previous frame
851         if ( pPrevFrm )
852         {
853             if ( pPrevFrm->IsSctFrm() )
854             {
855                 if ( pCnt->IsInSct() )
856                 {
857                     // Note: found previous frame is a section frame and
858                     //       <pCnt> is also inside a section.
859                     //       Thus due to <mbBordersJoinedWithPrev>,
860                     //       <pCnt> had joined its borders/shadow with the
861                     //       last content of the found section.
862                     // Invalidate printing area of last content in found section.
863                     SwFrm* pLstCntntOfSctFrm =
864                             static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
865                     if ( pLstCntntOfSctFrm )
866                     {
867                         pLstCntntOfSctFrm->InvalidatePrt();
868                     }
869                 }
870             }
871             else
872             {
873                 pPrevFrm->InvalidatePrt();
874             }
875         }
876     }
877 
878     sal_Bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
879 
880 	if ( pCnt->IsNoTxtFrm() )
881 	{
882 		//Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung
883 		//mitbekommen, damit sie Ihr Window entsprechend verschieben.
884 		ViewShell *pSh  = pCnt->getRootFrm()->GetCurrShell();
885 		if ( pSh )
886 		{
887             SwOLENode *pNd;
888 			if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
889 				 (pNd->GetOLEObj().IsOleRef() ||
890 				  pNd->IsOLESizeInvalid()) )
891 			{
892 				ASSERT( pCnt->IsInFly(), "OLE not in FlyFrm" );
893 				SwFlyFrm *pFly = pCnt->FindFlyFrm();
894                 svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
895 				SwFEShell *pFESh = 0;
896 				ViewShell *pTmp = pSh;
897 				do
898 				{	if ( pTmp->ISA( SwCrsrShell ) )
899 					{
900 						pFESh = (SwFEShell*)pTmp;
901                         // #108369#: Here used to be the condition if (!bFirst).
902                         // I think this should mean "do not call CalcAndSetScale"
903                         // if the frame is formatted for the first time.
904                         // Unfortunately this is not valid anymore since the
905                         // SwNoTxtFrm already gets a width during CalcLowerPreps.
906                         // Nevertheless, the indention of !bFirst seemed to be
907                         // to assure that the OLE objects have already been notified
908                         // if necessary before calling CalcAndSetScale.
909                         // So I replaced !bFirst by !IsOLESizeInvalid. There is
910                         // one additional problem specific to the word import:
911                         // The layout is calculated _before_ calling PrtOLENotify,
912                         // and the OLE objects are not invalidated during import.
913                         // Therefore I added the condition !IsUpdateExpFld,
914                         // have a look at the occurence of CalcLayout in
915                         // uiview/view.cxx.
916                         if ( !pNd->IsOLESizeInvalid() &&
917                              !pSh->GetDoc()->IsUpdateExpFld() )
918 							pFESh->CalcAndSetScale( xObj, &pFly->Prt(), &pFly->Frm());
919 					}
920 					pTmp = (ViewShell*)pTmp->GetNext();
921 				} while ( pTmp != pSh );
922 
923 				if ( pFESh && pNd->IsOLESizeInvalid() )
924 				{
925 					pNd->SetOLESizeInvalid( sal_False );
926                     //TODO/LATER: needs OnDocumentPrinterChanged
927                     //xObj->OnDocumentPrinterChanged( pNd->GetDoc()->getPrinter( false ) );
928 					pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
929 				}
930             }
931 			//dito Animierte Grafiken
932 			if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
933 			{
934 				((SwNoTxtFrm*)pCnt)->StopAnimation();
935 				pSh->InvalidateWindows( Frm() );
936 			}
937 		}
938 	}
939 
940 	if ( bFirst )
941 	{
942 		pCnt->SetRetouche();	//fix(13870)
943 
944 		SwDoc *pDoc = pCnt->GetNode()->GetDoc();
945 		if ( pDoc->GetSpzFrmFmts()->Count() &&
946 			 !pDoc->IsLoaded() && !pDoc->IsNewDoc() )
947 		{
948 			//Der Frm wurde wahrscheinlich zum ersten mal formatiert.
949 			//Wenn ein Filter Flys oder Zeichenobjekte einliest und diese
950 			//Seitengebunden sind, hat er ein Problem, weil er i.d.R. die
951 			//Seitennummer nicht kennt. Er weiss lediglich welches der Inhalt
952 			//(CntntNode) an dieser Stelle ist.
953 			//Die Filter stellen dazu das Ankerattribut der Objekte so ein, dass
954 			//sie vom Typ zwar Seitengebunden sind, aber der Index des Ankers
955 			//auf diesen CntntNode zeigt.
956 			//Hier werden diese vorlauefigen Verbindungen aufgeloest.
957 
958 			const SwPageFrm *pPage = 0;
959 			SwNodeIndex   *pIdx  = 0;
960 			SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
961 
962 			for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
963 			{
964 				if ( !pPage )
965 					pPage = pCnt->FindPageFrm();
966 				SwFrmFmt *pFmt = (*pTbl)[i];
967 				const SwFmtAnchor &rAnch = pFmt->GetAnchor();
968 
969                 if ((FLY_AT_PAGE != rAnch.GetAnchorId()) &&
970                     (FLY_AT_PARA != rAnch.GetAnchorId()))
971                 {
972 					continue;	//#60878# nicht etwa zeichengebundene.
973                 }
974 
975 				sal_Bool bCheckPos = sal_False;
976 				if ( rAnch.GetCntntAnchor() )
977 				{
978 					if ( !pIdx )
979 					{
980 						pIdx = new SwNodeIndex( *pCnt->GetNode() );
981 					}
982 					if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
983 					{
984                         bCheckPos = sal_True;
985                         if (FLY_AT_PAGE == rAnch.GetAnchorId())
986                         {
987                             ASSERT( false, "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
988 							SwFmtAnchor aAnch( rAnch );
989 							aAnch.SetAnchor( 0 );
990 							aAnch.SetPageNum( pPage->GetPhyPageNum() );
991                             pFmt->SetFmtAttr( aAnch );
992 							if ( RES_DRAWFRMFMT != pFmt->Which() )
993 								pFmt->MakeFrms();
994 						}
995 					}
996 				}
997             }
998             delete pIdx;
999         }
1000     }
1001 
1002     // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
1003     //  if height of last line has changed.
1004     if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
1005     {
1006         if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
1007         {
1008             pCnt->InvalidateNextPrtArea();
1009         }
1010     }
1011 
1012     // --> OD 2005-03-07 #i44049#
1013     if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
1014     {
1015         pCnt->InvalidateObjs( true );
1016     }
1017     // <--
1018 
1019     // --> OD 2005-04-12 #i43255# - move code to invalidate at-character
1020     // anchored objects due to a change of its anchor character from
1021     // method <SwTxtFrm::Format(..)>.
1022     if ( pCnt->IsTxtFrm() )
1023     {
1024         SwTxtFrm* pMasterFrm = pCnt->IsFollow()
1025                                ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
1026                                : static_cast<SwTxtFrm*>(pCnt);
1027         if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
1028              pMasterFrm->GetDrawObjs() )
1029         {
1030             SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
1031             for ( sal_uInt32 i = 0; i < pObjs->Count(); ++i )
1032             {
1033                 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1034                 if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
1035                         == FLY_AT_CHAR )
1036                 {
1037                     pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
1038                 }
1039             }
1040         }
1041     }
1042     // <--
1043 }
1044 
1045 /*************************************************************************/
1046 
1047 void AppendObjs( const SwSpzFrmFmts *pTbl, sal_uLong nIndex,
1048 						SwFrm *pFrm, SwPageFrm *pPage )
1049 {
1050 	for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
1051 	{
1052 		SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
1053 		const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1054 		if ( rAnch.GetCntntAnchor() &&
1055 			 (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
1056 		{
1057             const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
1058             //Wird ein Rahmen oder ein SdrObject beschrieben?
1059             const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
1060             // OD 23.06.2003 #108784# - append also drawing objects anchored
1061             // as character.
1062             const bool bDrawObjInCntnt = bSdrObj &&
1063                                          (rAnch.GetAnchorId() == FLY_AS_CHAR);
1064 
1065             if( bFlyAtFly ||
1066                 (rAnch.GetAnchorId() == FLY_AT_PARA) ||
1067                 (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
1068                 bDrawObjInCntnt )
1069 			{
1070                 SdrObject* pSdrObj = 0;
1071                 if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
1072 				{
1073 					ASSERT( !bSdrObj, "DrawObject not found." );
1074 					pFmt->GetDoc()->DelFrmFmt( pFmt );
1075 					--i;
1076 					continue;
1077 				}
1078 				if ( pSdrObj )
1079 				{
1080 					if ( !pSdrObj->GetPage() )
1081                     {
1082                         pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1083 								InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
1084                     }
1085 
1086                     SwDrawContact* pNew =
1087                         static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
1088                     if ( !pNew->GetAnchorFrm() )
1089                     {
1090                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
1091                     }
1092                     // OD 19.06.2003 #108784# - add 'virtual' drawing object,
1093                     // if necessary. But control objects have to be excluded.
1094                     else if ( !::CheckControlLayer( pSdrObj ) &&
1095                               pNew->GetAnchorFrm() != pFrm &&
1096                               !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
1097                     {
1098                         SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
1099                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
1100 
1101 						// for repaint, use new ActionChanged()
1102                         // pDrawVirtObj->SendRepaintBroadcast();
1103                         pDrawVirtObj->ActionChanged();
1104                     }
1105 
1106 				}
1107 				else
1108 				{
1109 					SwFlyFrm *pFly;
1110 					if( bFlyAtFly )
1111 						pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1112 					else
1113 						pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1114 					pFly->Lock();
1115 					pFrm->AppendFly( pFly );
1116 					pFly->Unlock();
1117 					if ( pPage )
1118 						::RegistFlys( pPage, pFly );
1119 				}
1120 			}
1121 		}
1122 	}
1123 }
1124 
1125 bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
1126 {
1127 	SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
1128 	if ( RES_FLYFRMFMT == pFmt->Which() )
1129     {
1130         const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
1131         const SwFlyFrm* pTmpFrm;
1132 		for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
1133         {
1134             if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
1135                 return true;
1136         }
1137     }
1138 	else
1139 	{
1140 		SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
1141 		if ( pContact )
1142             return pContact->GetAnchorFrm() != 0;
1143 	}
1144 	return false;
1145 }
1146 
1147 /** helper method to determine, if a <SwFrmFmt>, which has an object connected,
1148     is located in header or footer.
1149 
1150     OD 23.06.2003 #108784#
1151 
1152     @author OD
1153 */
1154 bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
1155 {
1156     bool bRetVal = false;
1157 
1158     const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
1159 
1160     if (rAnch.GetAnchorId() != FLY_AT_PAGE)
1161     {
1162         bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
1163     }
1164 
1165     return bRetVal;
1166 }
1167 
1168 void AppendAllObjs( const SwSpzFrmFmts *pTbl, const SwFrm* pSib )
1169 {
1170 	//Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem
1171 	//Layout.
1172 	//Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate
1173 	//uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch
1174 	//Objecte die in zeichengebundenen verankert sind.
1175 
1176 	SwSpzFrmFmts aCpy( 255, 255 );
1177 	aCpy.Insert( pTbl, 0 );
1178 
1179 	sal_uInt16 nOldCnt = USHRT_MAX;
1180 
1181 	while ( aCpy.Count() && aCpy.Count() != nOldCnt )
1182 	{
1183 		nOldCnt = aCpy.Count();
1184 		for ( int i = 0; i < int(aCpy.Count()); ++i )
1185 		{
1186 			SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
1187 			const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1188 			sal_Bool bRemove = sal_False;
1189             if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
1190                 (rAnch.GetAnchorId() == FLY_AS_CHAR))
1191             {
1192 				//Seitengebunde sind bereits verankert, zeichengebundene
1193 				//will ich hier nicht.
1194 				bRemove = sal_True;
1195             }
1196             else if ( sal_False == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
1197                       ::lcl_InHeaderOrFooter( *pFmt ) )
1198 			{
1199             // OD 23.06.2003 #108784# - correction: for objects in header
1200             // or footer create frames, in spite of the fact that an connected
1201             // objects already exists.
1202 				//Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch
1203 				//keine abhaengigen Existieren, andernfalls, oder wenn das
1204 				//MakeFrms keine abhaengigen erzeugt, entfernen.
1205 				pFmt->MakeFrms();
1206 				bRemove = ::lcl_ObjConnected( pFmt, pSib );
1207 			}
1208 			if ( bRemove )
1209 			{
1210 				aCpy.Remove( sal_uInt16(i) );
1211 				--i;
1212 			}
1213 		}
1214 	}
1215 	aCpy.Remove( 0, aCpy.Count() );
1216 }
1217 
1218 /** local method to set 'working' position for newly inserted frames
1219 
1220     OD 12.08.2003 #i17969#
1221 
1222     @author OD
1223 */
1224 void lcl_SetPos( SwFrm&             _rNewFrm,
1225                  const SwLayoutFrm& _rLayFrm )
1226 {
1227     SWRECTFN( (&_rLayFrm) )
1228     (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
1229     // move position by one SwTwip in text flow direction in order to get
1230     // notifications for a new calculated position after its formatting.
1231     if ( bVert )
1232         _rNewFrm.Frm().Pos().X() -= 1;
1233     else
1234         _rNewFrm.Frm().Pos().Y() += 1;
1235 }
1236 
1237 void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
1238 							 sal_uLong nIndex, sal_Bool bPages, sal_uLong nEndIndex,
1239 							 SwFrm *pPrv )
1240 {
1241 	pDoc->BlockIdling();
1242 	SwRootFrm* pLayout = pLay->getRootFrm();
1243     const sal_Bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
1244 	if( bOldCallbackActionEnabled )
1245         pLayout->SetCallbackActionEnabled( sal_False );
1246 
1247 	//Bei der Erzeugung des Layouts wird bPages mit sal_True uebergeben. Dann
1248 	//werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen
1249 	//und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten
1250 	//angelegt.
1251 	//Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von
1252 	//Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier
1253 	//lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf
1254 	//ertraegliches mass reduziert hat.
1255 	//Wir gehen mal davon aus, da? 20 Absaetze auf eine Seite passen
1256 	//Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach
1257 	//Node noch etwas drauf.
1258 	//Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
1259 	//(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
1260 	//ausgegengen.
1261 	const sal_Bool bStartPercent = bPages && !nEndIndex;
1262 
1263 	SwPageFrm *pPage = pLay->FindPageFrm();
1264 	const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1265 	SwFrm		*pFrm = 0;
1266 	sal_Bool   bBreakAfter	 = sal_False;
1267 
1268     SwActualSection *pActualSection = 0;
1269     SwLayHelper *pPageMaker;
1270 
1271     //Wenn das Layout erzeugt wird (bPages == sal_True) steuern wir den Progress
1272 	//an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
1273 	//passiert erst am Ende der Funktion.
1274     if ( bPages )
1275     {
1276         // Attention: the SwLayHelper class uses references to the content-,
1277         // page-, layout-frame etc. and may change them!
1278         pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
1279                 pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
1280         if( bStartPercent )
1281         {
1282             const sal_uLong nPageCount = pPageMaker->CalcPageCount();
1283             if( nPageCount )
1284                 bObjsDirect = sal_False;
1285         }
1286 	}
1287     else
1288         pPageMaker = NULL;
1289 
1290     if( pLay->IsInSct() &&
1291 		( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
1292 			// abgefangen, deren Flags noch nicht ermittelt werden koennen,
1293 			// so z.B. beim Einfuegen einer Tabelle
1294 	{
1295 		SwSectionFrm* pSct = pLay->FindSctFrm();
1296 		// Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen
1297 		// Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden.
1298 		// Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein
1299 		// Kandidat fuer pActualSection.
1300 		// Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle
1301 		// eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen,
1302 		// aufgebrochen werden.
1303 		if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
1304 			( !pLay->IsInTab() || pSct->IsInTab() ) )
1305 		{
1306 			pActualSection = new SwActualSection( 0, pSct, 0 );
1307 			ASSERT( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
1308 				"_InsertCnt: Wrong Call" );
1309 		}
1310 	}
1311 
1312     //If a section is "open", the pActualSection points to an SwActualSection.
1313     //If the page breaks, for "open" sections a follow will created.
1314     //For nested sections (which have, however, not a nested layout),
1315     //the SwActualSection class has a member, which points to an upper(section).
1316     //When the "inner" section finishs, the upper will used instead.
1317 
1318 	while( sal_True )
1319 	{
1320 		SwNode *pNd = pDoc->GetNodes()[nIndex];
1321 		if ( pNd->IsCntntNode() )
1322 		{
1323 			SwCntntNode* pNode = (SwCntntNode*)pNd;
1324 			pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode, pLay ) :
1325 										pNode->MakeFrm( pLay );
1326             if( pPageMaker )
1327                 pPageMaker->CheckInsert( nIndex );
1328 
1329             pFrm->InsertBehind( pLay, pPrv );
1330             // --> OD 2005-12-01 #i27138#
1331             // notify accessibility paragraphs objects about changed
1332             // CONTENT_FLOWS_FROM/_TO relation.
1333             // Relation CONTENT_FLOWS_FROM for next paragraph will change
1334             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1335             if ( pFrm->IsTxtFrm() )
1336             {
1337                 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1338                 // no notification, if <ViewShell> is in construction
1339                 if ( pViewShell && !pViewShell->IsInConstructor() &&
1340                      pViewShell->GetLayout() &&
1341                      pViewShell->GetLayout()->IsAnyShellAccessible() )
1342                 {
1343                     pViewShell->InvalidateAccessibleParaFlowRelation(
1344                         dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1345                         dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1346                     // --> OD 2006-08-28 #i68958#
1347                     // The information flags of the text frame are validated
1348                     // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
1349                     // The information flags have to be invalidated, because
1350                     // it is possible, that the one of its upper frames
1351                     // isn't inserted into the layout.
1352                     pFrm->InvalidateInfFlags();
1353                     // <--
1354                 }
1355             }
1356             // <--
1357             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1358             // for setting position at newly inserted frame
1359             lcl_SetPos( *pFrm, *pLay );
1360 			pPrv = pFrm;
1361 
1362 			if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
1363 				AppendObjs( pTbl, nIndex, pFrm, pPage );
1364 		}
1365 		else if ( pNd->IsTableNode() )
1366 		{	//Sollten wir auf eine Tabelle gestossen sein?
1367 			SwTableNode *pTblNode = (SwTableNode*)pNd;
1368 
1369             // #108116# loading may produce table structures that GCLines
1370             // needs to clean up. To keep table formulas correct, change
1371             // all table formulas to internal (BOXPTR) representation.
1372             SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
1373             aMsgHnt.eFlags = TBL_BOXPTR;
1374             pDoc->UpdateTblFlds( &aMsgHnt );
1375             pTblNode->GetTable().GCLines();
1376 
1377 			pFrm = pTblNode->MakeFrm( pLay );
1378 
1379             if( pPageMaker )
1380                 pPageMaker->CheckInsert( nIndex );
1381 
1382 			pFrm->InsertBehind( pLay, pPrv );
1383             // --> OD 2005-12-01 #i27138#
1384             // notify accessibility paragraphs objects about changed
1385             // CONTENT_FLOWS_FROM/_TO relation.
1386             // Relation CONTENT_FLOWS_FROM for next paragraph will change
1387             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1388             {
1389                 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1390                 // no notification, if <ViewShell> is in construction
1391                 if ( pViewShell && !pViewShell->IsInConstructor() &&
1392                      pViewShell->GetLayout() &&
1393                      pViewShell->GetLayout()->IsAnyShellAccessible() )
1394                 {
1395                     pViewShell->InvalidateAccessibleParaFlowRelation(
1396                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1397                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1398                 }
1399             }
1400             // <--
1401             if ( bObjsDirect && pTbl->Count() )
1402 				((SwTabFrm*)pFrm)->RegistFlys();
1403             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1404             // for setting position at newly inserted frame
1405             lcl_SetPos( *pFrm, *pLay );
1406 
1407             pPrv = pFrm;
1408 			//Index auf den Endnode der Tabellensection setzen.
1409 			nIndex = pTblNode->EndOfSectionIndex();
1410 
1411             SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
1412             while ( pTmpFrm )
1413             {
1414                 pTmpFrm->CheckDirChange();
1415                 pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
1416             }
1417 
1418 		}
1419 		else if ( pNd->IsSectionNode() )
1420 		{
1421 			SwSectionNode *pNode = (SwSectionNode*)pNd;
1422 			if( pNode->GetSection().CalcHiddenFlag() )
1423 				// ist versteckt, ueberspringe den Bereich
1424 				nIndex = pNode->EndOfSectionIndex();
1425 			else
1426 			{
1427                 pFrm = pNode->MakeFrm( pLay );
1428 				pActualSection = new SwActualSection( pActualSection,
1429 												(SwSectionFrm*)pFrm, pNode );
1430 				if ( pActualSection->GetUpper() )
1431 				{
1432 					//Hinter den Upper einsetzen, beim EndNode wird der "Follow"
1433 					//des Uppers erzeugt.
1434 					SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
1435 					pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
1436                     // OD 25.03.2003 #108339# - direct initialization of section
1437                     // after insertion in the layout
1438                     static_cast<SwSectionFrm*>(pFrm)->Init();
1439 				}
1440 				else
1441 				{
1442 					pFrm->InsertBehind( pLay, pPrv );
1443                     // OD 25.03.2003 #108339# - direct initialization of section
1444                     // after insertion in the layout
1445                     static_cast<SwSectionFrm*>(pFrm)->Init();
1446 
1447                     // --> FME 2004-09-08 #i33963#
1448                     // Do not trust the IsInFtn flag. If we are currently
1449                     // building up a table, the upper of pPrv may be a cell
1450                     // frame, but the cell frame does not have an upper yet.
1451                     if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
1452                     // <--
1453                     {
1454 						if( pPrv->IsSctFrm() )
1455 							pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
1456 						if( pPrv && pPrv->IsTxtFrm() )
1457 							((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, sal_False );
1458 					}
1459 				}
1460                 // --> OD 2005-12-01 #i27138#
1461                 // notify accessibility paragraphs objects about changed
1462                 // CONTENT_FLOWS_FROM/_TO relation.
1463                 // Relation CONTENT_FLOWS_FROM for next paragraph will change
1464                 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1465                 {
1466                     ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1467                     // no notification, if <ViewShell> is in construction
1468                     if ( pViewShell && !pViewShell->IsInConstructor() &&
1469                          pViewShell->GetLayout() &&
1470                          pViewShell->GetLayout()->IsAnyShellAccessible() )
1471                     {
1472                         pViewShell->InvalidateAccessibleParaFlowRelation(
1473                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1474                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1475                     }
1476                 }
1477                 // <--
1478                 pFrm->CheckDirChange();
1479 
1480                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1481                 // for setting position at newly inserted frame
1482                 lcl_SetPos( *pFrm, *pLay );
1483 
1484                 // OD 20.11.2002 #105405# - no page, no invalidate.
1485                 if ( pPage )
1486                 {
1487                     // OD 18.09.2002 #100522#
1488                     // invalidate page in order to force format and paint of
1489                     // inserted section frame
1490                     pFrm->InvalidatePage( pPage );
1491 
1492                     // FME 10.11.2003 #112243#
1493                     // Invalidate fly content flag:
1494                     if ( pFrm->IsInFly() )
1495                         pPage->InvalidateFlyCntnt();
1496 
1497                     // OD 14.11.2002 #104684# - invalidate page content in order to
1498                     // force format and paint of section content.
1499                     pPage->InvalidateCntnt();
1500                 }
1501 
1502 				pLay = (SwLayoutFrm*)pFrm;
1503 				if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1504 					pLay = pLay->GetNextLayoutLeaf();
1505 				pPrv = 0;
1506 			}
1507 		}
1508         else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
1509 		{
1510 			ASSERT( pActualSection, "Sectionende ohne Anfang?" );
1511             ASSERT( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
1512 							"Sectionende mit falschen Start Node?" );
1513 
1514 			//Section schliessen, ggf. die umgebende Section wieder
1515 			//aktivieren.
1516 			SwActualSection *pTmp = pActualSection->GetUpper();
1517 			delete pActualSection;
1518 			pLay = pLay->FindSctFrm();
1519 			if ( 0 != (pActualSection = pTmp) )
1520 			{
1521 				//Koennte noch sein, das der letzte SectionFrm leer geblieben
1522 				//ist. Dann ist es jetzt an der Zeit ihn zu entfernen.
1523 				if ( !pLay->ContainsCntnt() )
1524 				{
1525                     SwFrm *pTmpFrm = pLay;
1526                     pLay = pTmpFrm->GetUpper();
1527                     pPrv = pTmpFrm->GetPrev();
1528                     pTmpFrm->Remove();
1529                     delete pTmpFrm;
1530 				}
1531 				else
1532 				{
1533 					pPrv = pLay;
1534 					pLay = pLay->GetUpper();
1535 				}
1536 
1537                 // new section frame
1538                 pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
1539                 pFrm->InsertBehind( pLay, pPrv );
1540                 static_cast<SwSectionFrm*>(pFrm)->Init();
1541 
1542                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1543                 // for setting position at newly inserted frame
1544                 lcl_SetPos( *pFrm, *pLay );
1545 
1546                 SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
1547 
1548                 // a follow has to be appended to the new section frame
1549                 SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
1550                 if ( pFollow )
1551                 {
1552                     pOuterSectionFrm->SetFollow( NULL );
1553                     pOuterSectionFrm->InvalidateSize();
1554                     ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
1555                 }
1556 
1557 				// Wir wollen keine leeren Teile zuruecklassen
1558                 if( ! pOuterSectionFrm->IsColLocked() &&
1559                     ! pOuterSectionFrm->ContainsCntnt() )
1560 				{
1561                     pOuterSectionFrm->DelEmpty( sal_True );
1562                     delete pOuterSectionFrm;
1563 				}
1564 				pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
1565 
1566 				pLay = (SwLayoutFrm*)pFrm;
1567 				if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1568 					pLay = pLay->GetNextLayoutLeaf();
1569 				pPrv = 0;
1570 			}
1571 			else
1572 			{
1573 				//Nix mehr mit Sections, es geht direkt hinter dem SectionFrame
1574 				//weiter.
1575 				pPrv = pLay;
1576 				pLay = pLay->GetUpper();
1577 			}
1578 		}
1579 		else if( pNd->IsStartNode() &&
1580 				 SwFlyStartNode	== ((SwStartNode*)pNd)->GetStartNodeType() )
1581 		{
1582 			if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
1583 			{
1584 				SwFlyFrm* pFly = pLay->FindFlyFrm();
1585 				if( pFly )
1586 					AppendObjs( pTbl, nIndex, pFly, pPage );
1587 			}
1588 		}
1589 		else
1590 			// Weder Cntnt noch Tabelle noch Section,
1591 			// also muessen wir fertig sein.
1592 			break;
1593 
1594 		++nIndex;
1595 		// Der Endnode wird nicht mehr mitgenommen, es muss vom
1596 		// Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
1597 		// des Bereichs vor dem EndIndex liegt!
1598 		if ( nEndIndex && nIndex >= nEndIndex )
1599 			break;
1600 	}
1601 
1602 	if ( pActualSection )
1603 	{
1604 		//Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
1605 		if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
1606 		{
1607 			pLay->Remove();
1608 			delete pLay;
1609 		}
1610 		delete pActualSection;
1611 	}
1612 
1613 	if ( bPages )		//Jetzt noch die Flys verbinden lassen.
1614 	{
1615 		if ( !bDontCreateObjects )
1616 			AppendAllObjs( pTbl, pLayout );
1617 		bObjsDirect = sal_True;
1618 	}
1619 
1620     if( pPageMaker )
1621     {
1622         pPageMaker->CheckFlyCache( pPage );
1623         delete pPageMaker;
1624         if( pDoc->GetLayoutCache() )
1625         {
1626 #ifdef DBG_UTIL
1627 #if OSL_DEBUG_LEVEL > 1
1628             pDoc->GetLayoutCache()->CompareLayout( *pDoc );
1629 #endif
1630 #endif
1631             pDoc->GetLayoutCache()->ClearImpl();
1632         }
1633     }
1634 
1635     pDoc->UnblockIdling();
1636 	if( bOldCallbackActionEnabled )
1637         pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
1638 }
1639 
1640 
1641 void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
1642 			   const SwNodeIndex &rEndIdx )
1643 {
1644     bObjsDirect = sal_False;
1645 
1646 	SwNodeIndex aTmp( rSttIdx );
1647 	sal_uLong nEndIdx = rEndIdx.GetIndex();
1648     SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
1649 											pDoc->GetNodes()[ nEndIdx-1 ]);
1650 	if ( pNd )
1651 	{
1652 		sal_Bool bApres = aTmp < rSttIdx;
1653 		SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
1654 		SwFrm* pFrm;
1655 		while( 0 != (pFrm = aNode2Layout.NextFrm()) )
1656 		{
1657 			SwLayoutFrm *pUpper = pFrm->GetUpper();
1658 			SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
1659 			sal_Bool bOldLock, bOldFtn;
1660 			if( pFtnFrm )
1661 			{
1662 				bOldFtn = pFtnFrm->IsColLocked();
1663 				pFtnFrm->ColLock();
1664 			}
1665 			else
1666 				bOldFtn = sal_True;
1667 			SwSectionFrm* pSct = pUpper->FindSctFrm();
1668 			// Es sind innerhalb von Fussnoten nur die Bereiche interessant,
1669 			// die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
1670 			// in denen die Fussnoten(Container) liegen.
1671             // #109767# Table frame is in section, insert section in cell frame.
1672 			if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
1673 				pSct = NULL;
1674 			if( pSct )
1675 			{   // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
1676 				bOldLock = pSct->IsColLocked();
1677 				pSct->ColLock();
1678 			}
1679 			else
1680 				bOldLock = sal_True;
1681 
1682             // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
1683 			// auf die naechste Seite schieben. Innerhalb eines Rahmens auch
1684 			// nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
1685 			// Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
1686             sal_Bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
1687             sal_Bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
1688                  (!pFrm->IsInTab() || pFrm->IsTabFrm() );
1689             if ( bMoveNext && bAllowMove )
1690 			{
1691 				SwFrm *pMove = pFrm;
1692 				SwFrm *pPrev = pFrm->GetPrev();
1693 				SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
1694 				ASSERT( pTmp, "Missing FlowFrm" );
1695 
1696 				if ( bApres )
1697 				{
1698 					// Wir wollen, dass der Rest der Seite leer ist, d.h.
1699 					// der naechste muss auf die naechste Seite wandern.
1700 					// Dieser kann auch in der naechsten Spalte stehen!
1701 					ASSERT( !pTmp->HasFollow(), "Follows forbidden" );
1702 					pPrev = pFrm;
1703 					// Wenn unser umgebender SectionFrm einen Next besitzt,
1704 					// so soll dieser ebenfalls gemoved werden!
1705 					pMove = pFrm->GetIndNext();
1706 					SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
1707 					if( pCol )
1708 						pCol = (SwColumnFrm*)pCol->GetNext();
1709 					do
1710 					{
1711 						if( pCol && !pMove )
1712 						{   // Bisher haben wir keinen Nachfolger gefunden
1713 							// jetzt gucken wir in die naechste Spalte
1714 							pMove = pCol->ContainsAny();
1715 							if( pCol->GetNext() )
1716 								pCol = (SwColumnFrm*)pCol->GetNext();
1717 							else if( pCol->IsInSct() )
1718 							{   // Wenn es keine naechste Spalte gibt, wir aber
1719 								// innerhalb eines spaltigen Bereichs sind,
1720 								// koennte es noch ausserhalb des Bereich
1721 								// (Seiten-)Spalten geben
1722 								pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
1723 								if( pCol )
1724 									pCol = (SwColumnFrm*)pCol->GetNext();
1725 							}
1726 							else
1727 								pCol = NULL;
1728 						}
1729 						// Falls hier verschrottete SectionFrms herumgammeln,
1730 						// muessen diese uebersprungen werden.
1731 						while( pMove && pMove->IsSctFrm() &&
1732 							   !((SwSectionFrm*)pMove)->GetSection() )
1733 							pMove = pMove->GetNext();
1734 					} while( !pMove && pCol );
1735 
1736 					if( pMove )
1737 					{
1738 						if ( pMove->IsCntntFrm() )
1739 							pTmp = (SwCntntFrm*)pMove;
1740 						else if ( pMove->IsTabFrm() )
1741 							pTmp = (SwTabFrm*)pMove;
1742 						else if ( pMove->IsSctFrm() )
1743 						{
1744 							pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1745 							if( pMove )
1746 								pTmp = SwFlowFrm::CastFlowFrm( pMove );
1747 							else
1748 								pTmp = NULL;
1749 						}
1750 					}
1751 					else
1752 						pTmp = 0;
1753 				}
1754 				else
1755 				{
1756 					ASSERT( !pTmp->IsFollow(), "Follows really forbidden" );
1757 					// Bei Bereichen muss natuerlich der Inhalt auf die Reise
1758 					// geschickt werden.
1759 					if( pMove->IsSctFrm() )
1760 					{
1761 						while( pMove && pMove->IsSctFrm() &&
1762 							   !((SwSectionFrm*)pMove)->GetSection() )
1763 							pMove = pMove->GetNext();
1764 						if( pMove && pMove->IsSctFrm() )
1765 							pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1766 						if( pMove )
1767 							pTmp = SwFlowFrm::CastFlowFrm( pMove );
1768 						else
1769 							pTmp = NULL;
1770 					}
1771 				}
1772 
1773 				if( pTmp )
1774 				{
1775 					SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
1776 					// MoveFwd==sal_True bedeutet, dass wir auf der gleichen
1777 					// Seite geblieben sind, wir wollen aber die Seite wechseln,
1778 					// sofern dies moeglich ist
1779                     sal_Bool bTmpOldLock = pTmp->IsJoinLocked();
1780 					pTmp->LockJoin();
1781 					while( pTmp->MoveFwd( sal_True, sal_False, sal_True ) )
1782 					{
1783 						if( pOldUp == pTmp->GetFrm()->GetUpper() )
1784 							break;
1785 						pOldUp = pTmp->GetFrm()->GetUpper();
1786 					}
1787                     if( !bTmpOldLock )
1788 						pTmp->UnlockJoin();
1789 				}
1790 				::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
1791 							  pFrm->IsInDocBody(), nEndIdx, pPrev );
1792 			}
1793 			else
1794 			{
1795 				sal_Bool bSplit;
1796 				SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
1797 				// Wenn in einen SectionFrm ein anderer eingefuegt wird,
1798 				// muss dieser aufgebrochen werden
1799 				if( pSct && rSttIdx.GetNode().IsSectionNode() )
1800 				{
1801 					bSplit = pSct->SplitSect( pFrm, bApres );
1802 					// Wenn pSct nicht aufgespalten werden konnte
1803 					if( !bSplit && !bApres )
1804 					{
1805 						pUpper = pSct->GetUpper();
1806 						pPrv = pSct->GetPrev();
1807 					}
1808 				}
1809 				else
1810 					bSplit = sal_False;
1811                 ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), sal_False,
1812                               nEndIdx, pPrv );
1813                 // OD 23.06.2003 #108784# - correction: append objects doesn't
1814                 // depend on value of <bAllowMove>
1815                 if( !bDontCreateObjects )
1816                 {
1817                     const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1818                     if( pTbl->Count() )
1819                         AppendAllObjs( pTbl, pUpper );
1820                 }
1821 
1822 				// Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
1823 				// muss das Splitten rueckgaengig gemacht werden
1824 				if( bSplit && pSct && pSct->GetNext()
1825 					&& pSct->GetNext()->IsSctFrm() )
1826 					pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
1827 				if( pFrm->IsInFly() )
1828 					pFrm->FindFlyFrm()->_Invalidate();
1829 				if( pFrm->IsInTab() )
1830 					pFrm->InvalidateSize();
1831 			}
1832 
1833 			SwPageFrm *pPage = pUpper->FindPageFrm();
1834 			SwFrm::CheckPageDescs( pPage, sal_False );
1835 			if( !bOldFtn )
1836 				pFtnFrm->ColUnlock();
1837 			if( !bOldLock )
1838 			{
1839 				pSct->ColUnlock();
1840 				// Zum Beispiel beim Einfuegen von gelinkten Bereichen,
1841 				// die wiederum Bereiche enthalten, kann pSct jetzt leer sein
1842 				// und damit ruhig zerstoert werden.
1843 				if( !pSct->ContainsCntnt() )
1844 				{
1845 					pSct->DelEmpty( sal_True );
1846 					pUpper->getRootFrm()->RemoveFromList( pSct );
1847 					delete pSct;
1848 				}
1849 			}
1850 		}
1851 	}
1852 
1853     bObjsDirect = sal_True;
1854 }
1855 
1856 
1857 /*************************************************************************/
1858 
1859 SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
1860 	SwCacheObj( pMod ),
1861 	rAttrSet( pConstructor->IsCntntFrm()
1862 					? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
1863 					: ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
1864 	rUL 	( rAttrSet.GetULSpace() ),
1865     // --> OD 2008-12-04 #i96772#
1866     // LRSpaceItem is copied due to the possibility that it is adjusted - see below
1867     rLR     ( rAttrSet.GetLRSpace() ),
1868     // <--
1869 	rBox	( rAttrSet.GetBox() 	),
1870 	rShadow ( rAttrSet.GetShadow()	),
1871 	aFrmSize( rAttrSet.GetFrmSize().GetSize() )
1872 {
1873     // --> OD 2008-12-02 #i96772#
1874     const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
1875     if ( pTxtFrm )
1876     {
1877         pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
1878     }
1879 
1880 	//Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
1881 	//nicht initialisiert!
1882 
1883 	//Muessen alle einmal berechnet werden:
1884 	bTopLine = bBottomLine = bLeftLine = bRightLine =
1885     bTop     = bBottom     = bLine   = sal_True;
1886 
1887 	bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = sal_False;
1888     // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
1889     // and <bJoinedWithNext>, which aren't initialized by default.
1890     bCachedJoinedWithPrev = sal_False;
1891     bCachedJoinedWithNext = sal_False;
1892 
1893 	bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
1894 }
1895 
1896 SwBorderAttrs::~SwBorderAttrs()
1897 {
1898 	((SwModify*)pOwner)->SetInCache( sal_False );
1899 }
1900 
1901 /*************************************************************************
1902 |*
1903 |*	SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
1904 |*
1905 |*	Beschreibung		Die Calc-Methoden errechnen zusaetzlich zu den
1906 |*		von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
1907 |*		der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
1908 |*		Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
1909 |*		groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
1910 |*
1911 |*************************************************************************/
1912 
1913 void SwBorderAttrs::_CalcTop()
1914 {
1915 	nTop = CalcTopLine() + rUL.GetUpper();
1916 	bTop = sal_False;
1917 }
1918 
1919 void SwBorderAttrs::_CalcBottom()
1920 {
1921 	nBottom = CalcBottomLine() + rUL.GetLower();
1922 	bBottom = sal_False;
1923 }
1924 
1925 long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
1926 {
1927     long nRight;
1928 
1929     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1930     // and right border are painted on the right respectively left.
1931     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1932         nRight = CalcLeftLine();
1933     else
1934         nRight = CalcRightLine();
1935 
1936     // for paragraphs, "left" is "before text" and "right" is "after text"
1937     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1938         nRight += rLR.GetLeft();
1939     else
1940         nRight += rLR.GetRight();
1941 
1942     // --> OD 2008-01-21 #newlistlevelattrs#
1943     // correction: retrieve left margin for numbering in R2L-layout
1944     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1945     {
1946         nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1947     }
1948     // <--
1949 
1950     return nRight;
1951 }
1952 
1953 long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
1954 {
1955     long nLeft;
1956 
1957     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1958     // and right border are painted on the right respectively left.
1959     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1960         nLeft = CalcRightLine();
1961     else
1962         nLeft = CalcLeftLine();
1963 
1964     // for paragraphs, "left" is "before text" and "right" is "after text"
1965     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1966         nLeft += rLR.GetRight();
1967     else
1968         nLeft += rLR.GetLeft();
1969 
1970     // --> OD 2008-01-21 #newlistlevelattrs#
1971     // correction: do not retrieve left margin for numbering in R2L-layout
1972 //    if ( pCaller->IsTxtFrm() )
1973     if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
1974     // <--
1975     {
1976         nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1977     }
1978 
1979     return nLeft;
1980 }
1981 
1982 /*************************************************************************
1983 |*
1984 |*	SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
1985 |*				   CalcLeftLine(), CalcRightLine()
1986 |*
1987 |*	Beschreibung		Berechnung der Groessen fuer Umrandung und Schatten.
1988 |* 						Es kann auch ohne Linien ein Abstand erwuenscht sein,
1989 |* 						dieser wird  dann nicht vom Attribut sondern hier
1990 |* 						beruecksichtigt (bBorderDist, z.B. fuer Zellen).
1991 |*
1992 |*************************************************************************/
1993 
1994 void SwBorderAttrs::_CalcTopLine()
1995 {
1996 	nTopLine = (bBorderDist && !rBox.GetTop())
1997 							? rBox.GetDistance  (BOX_LINE_TOP)
1998 							: rBox.CalcLineSpace(BOX_LINE_TOP);
1999 	nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
2000 	bTopLine = sal_False;
2001 }
2002 
2003 void SwBorderAttrs::_CalcBottomLine()
2004 {
2005 	nBottomLine = (bBorderDist && !rBox.GetBottom())
2006 							? rBox.GetDistance  (BOX_LINE_BOTTOM)
2007 							: rBox.CalcLineSpace(BOX_LINE_BOTTOM);
2008 	nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
2009 	bBottomLine = sal_False;
2010 }
2011 
2012 void SwBorderAttrs::_CalcLeftLine()
2013 {
2014 	nLeftLine = (bBorderDist && !rBox.GetLeft())
2015 							? rBox.GetDistance  (BOX_LINE_LEFT)
2016 							: rBox.CalcLineSpace(BOX_LINE_LEFT);
2017 	nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
2018 	bLeftLine = sal_False;
2019 }
2020 
2021 void SwBorderAttrs::_CalcRightLine()
2022 {
2023 	nRightLine = (bBorderDist && !rBox.GetRight())
2024 							? rBox.GetDistance  (BOX_LINE_RIGHT)
2025 							: rBox.CalcLineSpace(BOX_LINE_RIGHT);
2026 	nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
2027 	bRightLine = sal_False;
2028 }
2029 
2030 /*************************************************************************/
2031 
2032 void SwBorderAttrs::_IsLine()
2033 {
2034 	bIsLine = rBox.GetTop() || rBox.GetBottom() ||
2035 			  rBox.GetLeft()|| rBox.GetRight();
2036 	bLine = sal_False;
2037 }
2038 
2039 /*************************************************************************
2040 |*
2041 |*	SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
2042 |*
2043 |*		Die Umrandungen benachbarter Absaetze werden nach folgendem
2044 |*		Algorithmus zusammengefasst:
2045 |*
2046 |*		1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
2047 |*		   Umrandung oben aufweist und 3. Zutrifft.
2048 |*		   Zusaetzlich muss der Absatz mindestens rechts oder links oder
2049 |*		   unten eine Umrandung haben.
2050 |*		2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
2051 |*		   Umrandung untern aufweist und 3. Zustrifft.
2052 |*		   Zusaetzlich muss der Absatz mindestens rechts oder links oder
2053 |*		   oben eine Umrandung haben.
2054 |*		3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
2055 |*		   sind identisch.
2056 |*
2057 |*************************************************************************/
2058 inline int CmpLines( const SvxBorderLine *pL1, const SvxBorderLine *pL2 )
2059 {
2060 	return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
2061 }
2062 
2063 // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
2064 // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
2065 //          instead of only the right LR-spacing, because R2L-layout has to be
2066 //          considered.
2067 sal_Bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
2068 								  const SwFrm *pCaller,
2069 								  const SwFrm *pCmp ) const
2070 {
2071     return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft()  ) &&
2072              CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
2073              CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
2074              // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
2075              CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
2076 }
2077 
2078 sal_Bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
2079                                   const SwFrm& _rCmpFrm ) const
2080 {
2081     sal_Bool bReturnVal = sal_False;
2082 
2083     SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
2084     const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
2085     if ( rShadow == rCmpAttrs.GetShadow() &&
2086          CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
2087          CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
2088          CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
2089        )
2090     {
2091         bReturnVal = sal_True;
2092     }
2093 
2094     return bReturnVal;
2095 }
2096 
2097 // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2098 // previous frame. Calculated value saved in cached value <bJoinedWithPrev>
2099 // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
2100 void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
2101                                          const SwFrm* _pPrevFrm )
2102 {
2103     // set default
2104     bJoinedWithPrev = sal_False;
2105 
2106     if ( _rFrm.IsTxtFrm() )
2107     {
2108         // text frame can potentially join with previous text frame, if
2109         // corresponding attribute set is set at previous text frame.
2110         // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
2111         // one as previous frame.
2112         const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
2113         // OD 2004-02-13 #i25029# - skip hidden text frames.
2114         while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2115                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
2116         {
2117             pPrevFrm = pPrevFrm->GetPrev();
2118         }
2119         if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2120              pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
2121            )
2122         {
2123             bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
2124         }
2125     }
2126 
2127     // valid cache status, if demanded
2128     // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
2129     // is set.
2130     bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
2131 }
2132 
2133 // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2134 // next frame. Calculated value saved in cached value <bJoinedWithNext>
2135 void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
2136 {
2137     // set default
2138     bJoinedWithNext = sal_False;
2139 
2140     if ( _rFrm.IsTxtFrm() )
2141     {
2142         // text frame can potentially join with next text frame, if
2143         // corresponding attribute set is set at current text frame.
2144         // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
2145         const SwFrm* pNextFrm = _rFrm.GetNext();
2146         while ( pNextFrm && pNextFrm->IsTxtFrm() &&
2147                 static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
2148         {
2149             pNextFrm = pNextFrm->GetNext();
2150         }
2151         if ( pNextFrm && pNextFrm->IsTxtFrm() &&
2152              _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
2153            )
2154         {
2155             bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
2156         }
2157     }
2158 
2159     // valid cache status, if demanded
2160     bCachedJoinedWithNext = bCacheGetLine;
2161 }
2162 
2163 // OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
2164 // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
2165 // method <_CalcJoindWithPrev(..)>.
2166 sal_Bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
2167                                     const SwFrm* _pPrevFrm ) const
2168 {
2169     if ( !bCachedJoinedWithPrev || _pPrevFrm )
2170     {
2171         // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
2172         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
2173     }
2174 
2175     return bJoinedWithPrev;
2176 }
2177 
2178 sal_Bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
2179 {
2180     if ( !bCachedJoinedWithNext )
2181     {
2182         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
2183     }
2184 
2185     return bJoinedWithNext;
2186 }
2187 
2188 // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
2189 // method <JoinedWithPrev>
2190 void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
2191                                  const SwFrm* _pPrevFrm )
2192 {
2193     sal_uInt16 nRet = CalcTopLine();
2194 
2195     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2196     // OD 2004-02-26 #i25029# - add 2nd parameter
2197     if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
2198     {
2199         nRet = 0;
2200     }
2201 
2202     bCachedGetTopLine = bCacheGetLine;
2203 
2204 	nGetTopLine = nRet;
2205 }
2206 
2207 void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
2208 {
2209 	sal_uInt16 nRet = CalcBottomLine();
2210 
2211     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2212     if ( JoinedWithNext( _rFrm ) )
2213     {
2214         nRet = 0;
2215     }
2216 
2217     bCachedGetBottomLine = bCacheGetLine;
2218 
2219 	nGetBottomLine = nRet;
2220 }
2221 
2222 /*************************************************************************/
2223 
2224 SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
2225     SwCacheAccess( rCach, (pFrm->IsCntntFrm() ?
2226 								(void*)((SwCntntFrm*)pFrm)->GetNode() :
2227 								(void*)((SwLayoutFrm*)pFrm)->GetFmt()),
2228 						   (sal_Bool)(pFrm->IsCntntFrm() ?
2229 				((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
2230 				((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
2231 	pConstructor( pFrm )
2232 {
2233 }
2234 
2235 /*************************************************************************/
2236 
2237 SwCacheObj *SwBorderAttrAccess::NewObj()
2238 {
2239 	((SwModify*)pOwner)->SetInCache( sal_True );
2240 	return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
2241 }
2242 
2243 SwBorderAttrs *SwBorderAttrAccess::Get()
2244 {
2245 	return (SwBorderAttrs*)SwCacheAccess::Get();
2246 }
2247 
2248 /*************************************************************************/
2249 
2250 SwOrderIter::SwOrderIter( const SwPageFrm *pPg, sal_Bool bFlys ) :
2251 	pPage( pPg ),
2252 	pCurrent( 0 ),
2253 	bFlysOnly( bFlys )
2254 {
2255 }
2256 
2257 /*************************************************************************/
2258 
2259 const SdrObject *SwOrderIter::Top()
2260 {
2261 	pCurrent = 0;
2262 	if ( pPage->GetSortedObjs() )
2263 	{
2264 		sal_uInt32 nTopOrd = 0;
2265         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2266 		if ( pObjs->Count() )
2267 		{
2268             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2269 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2270 			{
2271                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2272 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2273 					continue;
2274 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2275 				if ( nTmp >= nTopOrd )
2276 				{
2277 					nTopOrd = nTmp;
2278 					pCurrent = pObj;
2279 				}
2280 			}
2281 		}
2282 	}
2283 	return pCurrent;
2284 }
2285 
2286 /*************************************************************************/
2287 
2288 const SdrObject *SwOrderIter::Bottom()
2289 {
2290 	pCurrent = 0;
2291 	if ( pPage->GetSortedObjs() )
2292 	{
2293 		sal_uInt32 nBotOrd = USHRT_MAX;
2294         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2295 		if ( pObjs->Count() )
2296 		{
2297             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2298 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2299 			{
2300                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2301 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2302 					continue;
2303 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2304 				if ( nTmp < nBotOrd )
2305 				{
2306 					nBotOrd = nTmp;
2307 					pCurrent = pObj;
2308 				}
2309 			}
2310 		}
2311 	}
2312 	return pCurrent;
2313 }
2314 
2315 /*************************************************************************/
2316 
2317 const SdrObject *SwOrderIter::Next()
2318 {
2319 	const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2320 	pCurrent = 0;
2321 	if ( pPage->GetSortedObjs() )
2322 	{
2323 		sal_uInt32 nOrd = USHRT_MAX;
2324         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2325 		if ( pObjs->Count() )
2326 		{
2327             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2328 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2329 			{
2330                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2331 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2332 					continue;
2333 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2334 				if ( nTmp > nCurOrd && nTmp < nOrd )
2335 				{
2336 					nOrd = nTmp;
2337 					pCurrent = pObj;
2338 				}
2339 			}
2340 		}
2341 	}
2342 	return pCurrent;
2343 }
2344 
2345 /*************************************************************************/
2346 
2347 const SdrObject *SwOrderIter::Prev()
2348 {
2349 	const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2350 	pCurrent = 0;
2351 	if ( pPage->GetSortedObjs() )
2352 	{
2353 		sal_uInt32 nOrd = 0;
2354         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2355 		if ( pObjs->Count() )
2356 		{
2357             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2358 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2359 			{
2360                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2361 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2362 					continue;
2363 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2364 				if ( nTmp < nCurOrd && nTmp >= nOrd )
2365 				{
2366 					nOrd = nTmp;
2367 					pCurrent = pObj;
2368 				}
2369 			}
2370 		}
2371 	}
2372 	return pCurrent;
2373 }
2374 
2375 /*************************************************************************/
2376 
2377 //Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
2378 //restaurieren.
2379 //Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
2380 //die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
2381 //Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
2382 //Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
2383 //angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
2384 //die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
2385 //auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
2386 //Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
2387 //verboten.
2388 //Unterwegs werden die Flys bei der Seite abgemeldet.
2389 
2390 // --> OD 2004-11-29 #115759# - 'remove' also drawing object from page and
2391 // at-fly anchored objects from page
2392 void MA_FASTCALL lcl_RemoveObjsFromPage( SwFrm* _pFrm )
2393 {
2394     ASSERT( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
2395     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2396 	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2397 	{
2398         SwAnchoredObject* pObj = rObjs[i];
2399         // --> OD 2004-11-29 #115759# - reset member, at which the anchored
2400         // object orients its vertical position
2401         pObj->ClearVertPosOrientFrm();
2402         // <--
2403         // --> OD 2005-03-03 #i43913#
2404         pObj->ResetLayoutProcessBools();
2405         // <--
2406         // --> OD 2004-11-29 #115759# - remove also lower objects of as-character
2407         // anchored Writer fly frames from page
2408         if ( pObj->ISA(SwFlyFrm) )
2409         {
2410             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2411 
2412             // --> OD 2004-11-29 #115759# - remove also direct lowers of Writer
2413             // fly frame from page
2414             if ( pFlyFrm->GetDrawObjs() )
2415             {
2416                 ::lcl_RemoveObjsFromPage( pFlyFrm );
2417             }
2418             // <--
2419 
2420             SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
2421             while ( pCnt )
2422             {
2423                 if ( pCnt->GetDrawObjs() )
2424                     ::lcl_RemoveObjsFromPage( pCnt );
2425                 pCnt = pCnt->GetNextCntntFrm();
2426             }
2427             if ( pFlyFrm->IsFlyFreeFrm() )
2428             {
2429                 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
2430                 pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
2431             }
2432         }
2433         // <--
2434         // --> OD 2004-11-29 #115759# - remove also drawing objects from page
2435         else if ( pObj->ISA(SwAnchoredDrawObject) )
2436         {
2437             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2438             {
2439                 pObj->GetPageFrm()->RemoveDrawObjFromPage(
2440                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2441             }
2442         }
2443         // <--
2444 	}
2445 }
2446 
2447 SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
2448 {
2449 	if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
2450 		lcl_RemoveFtns( (SwColumnFrm*)pLay->Lower(), sal_True, sal_True );
2451 
2452 	SwFrm *pSav;
2453 	if ( 0 == (pSav = pLay->ContainsAny()) )
2454 		return 0;
2455 
2456 	if( pSav->IsInFtn() && !pLay->IsInFtn() )
2457 	{
2458 		do
2459 			pSav = pSav->FindNext();
2460 		while( pSav && pSav->IsInFtn() );
2461 		if( !pSav || !pLay->IsAnLower( pSav ) )
2462 			return NULL;
2463 	}
2464 
2465     // Tables should be saved as a whole, expection:
2466     // The contents of a section or a cell inside a table should be saved
2467     if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
2468         while ( !pSav->IsTabFrm() )
2469             pSav = pSav->GetUpper();
2470 
2471 	if( pSav->IsInSct() )
2472 	{ // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
2473 		SwFrm* pSect = pLay->FindSctFrm();
2474 		SwFrm *pTmp = pSav;
2475 		do
2476 		{
2477 			pSav = pTmp;
2478 			pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
2479 		} while ( pTmp != pSect );
2480 	}
2481 
2482 	SwFrm *pFloat = pSav;
2483 	if( !pStart )
2484 		pStart = pSav;
2485 	sal_Bool bGo = pStart == pSav;
2486 	do
2487 	{
2488 		if( bGo )
2489 			pFloat->GetUpper()->pLower = 0; 	//Die Teilkette ausklinken.
2490 
2491 		//Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
2492 		do
2493 		{
2494 			if( bGo )
2495 			{
2496 				if ( pFloat->IsCntntFrm() )
2497 				{
2498 					if ( pFloat->GetDrawObjs() )
2499                         ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
2500 				}
2501 				else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
2502 				{
2503 					SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
2504 					if( pCnt )
2505 					{
2506 						do
2507 						{	if ( pCnt->GetDrawObjs() )
2508                                 ::lcl_RemoveObjsFromPage( pCnt );
2509 							pCnt = pCnt->GetNextCntntFrm();
2510 						} while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
2511 					}
2512 				}
2513 				else {
2514 					ASSERT( !pFloat, "Neuer Float-Frame?" );
2515                 }
2516 			}
2517 			if ( pFloat->GetNext()	)
2518 			{
2519 				if( bGo )
2520 					pFloat->pUpper = NULL;
2521 				pFloat = pFloat->GetNext();
2522 				if( !bGo && pFloat == pStart )
2523 				{
2524 					bGo = sal_True;
2525 					pFloat->pPrev->pNext = NULL;
2526 					pFloat->pPrev = NULL;
2527 				}
2528 			}
2529 			else
2530 				break;
2531 
2532 		} while ( pFloat );
2533 
2534 		//Die naechste Teilkette suchen und die Ketten miteinander verbinden.
2535 		SwFrm *pTmp = pFloat->FindNext();
2536 		if( bGo )
2537 			pFloat->pUpper = NULL;
2538 
2539 		if( !pLay->IsInFtn() )
2540 			while( pTmp && pTmp->IsInFtn() )
2541 				pTmp = pTmp->FindNext();
2542 
2543 		if ( !pLay->IsAnLower( pTmp ) )
2544 			pTmp = 0;
2545 
2546 		if ( pTmp && bGo )
2547 		{
2548 			pFloat->pNext = pTmp;			//Die beiden Ketten verbinden.
2549 			pFloat->pNext->pPrev = pFloat;
2550 		}
2551 		pFloat = pTmp;
2552 		bGo = bGo || ( pStart == pFloat );
2553 	}  while ( pFloat );
2554 
2555 	return bGo ? pStart : NULL;
2556 }
2557 
2558 // --> OD 2004-11-29 #115759# - add also drawing objects to page and at-fly
2559 // anchored objects to page
2560 void MA_FASTCALL lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
2561 {
2562     ASSERT( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
2563     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2564 	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2565 	{
2566         SwAnchoredObject* pObj = rObjs[i];
2567 
2568         // --> OD 2004-11-29 #115759# - unlock position of anchored object
2569         // in order to get the object's position calculated.
2570         pObj->UnlockPosition();
2571         // <--
2572         // --> OD 2004-11-29 #115759# - add also lower objects of as-character
2573         // anchored Writer fly frames from page
2574         if ( pObj->ISA(SwFlyFrm) )
2575         {
2576             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2577             if ( pObj->ISA(SwFlyFreeFrm) )
2578             {
2579                 _pPage->AppendFlyToPage( pFlyFrm );
2580             }
2581             pFlyFrm->_InvalidatePos();
2582             pFlyFrm->_InvalidateSize();
2583             pFlyFrm->InvalidatePage( _pPage );
2584 
2585             // --> OD 2004-11-29 #115759# - add also at-fly anchored objects
2586             // to page
2587             if ( pFlyFrm->GetDrawObjs() )
2588             {
2589                 ::lcl_AddObjsToPage( pFlyFrm, _pPage );
2590             }
2591             // <--
2592 
2593             SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
2594             while ( pCnt )
2595             {
2596                 if ( pCnt->GetDrawObjs() )
2597                     ::lcl_AddObjsToPage( pCnt, _pPage );
2598                 pCnt = pCnt->GetNextCntntFrm();
2599             }
2600         }
2601         // <--
2602         // --> OD 2004-11-29 #115759# - remove also drawing objects from page
2603         else if ( pObj->ISA(SwAnchoredDrawObject) )
2604         {
2605             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2606             {
2607                 pObj->InvalidateObjPos();
2608                 _pPage->AppendDrawObjToPage(
2609                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2610             }
2611         }
2612         // <--
2613 	}
2614 }
2615 
2616 void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
2617 {
2618 	ASSERT( pSav && pParent, "Kein Save oder Parent fuer Restore." );
2619     SWRECTFN( pParent )
2620 
2621 	//Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
2622 	//Kette, beginnend mit pSav,  hinter dem letzten angehaengt.
2623 	//Die Teile werden kurzerhand insertet und geeignet invalidiert.
2624 	//Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.
2625 
2626 	SwPageFrm *pPage = pParent->FindPageFrm();
2627 
2628 	if ( pPage )
2629 		pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.
2630 
2631 	//Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
2632 	pSav->pPrev = pSibling;
2633 	SwFrm* pNxt;
2634 	if ( pSibling )
2635 	{
2636 		pNxt = pSibling->pNext;
2637 		pSibling->pNext = pSav;
2638 		pSibling->_InvalidatePrt();
2639 		((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
2640 		if ( ((SwCntntFrm*)pSibling)->GetFollow() )
2641 			pSibling->Prepare( PREP_CLEAR, 0, sal_False );
2642 	}
2643 	else
2644 	{	pNxt = pParent->pLower;
2645 		pParent->pLower = pSav;
2646 		pSav->pUpper = pParent;		//Schon mal setzen, sonst ist fuer das
2647 									//invalidate der Parent (z.B. ein Fly) nicht klar.
2648 		//Invaliden Cntnt anmelden.
2649 		if ( pSav->IsCntntFrm() )
2650 			((SwCntntFrm*)pSav)->InvalidatePage( pPage );
2651 		else
2652 		{   // pSav koennte auch ein leerer SectFrm sein
2653 			SwCntntFrm* pCnt = pParent->ContainsCntnt();
2654 			if( pCnt )
2655 				pCnt->InvalidatePage( pPage );
2656 		}
2657 	}
2658 
2659 	//Der Parent muss entsprechend gegrow'ed werden.
2660 	SwTwips nGrowVal = 0;
2661 	SwFrm* pLast;
2662 	do
2663 	{	pSav->pUpper = pParent;
2664 		nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
2665 		pSav->_InvalidateAll();
2666 
2667         //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
2668 		if ( pSav->IsCntntFrm() )
2669 		{
2670 			if ( pSav->IsTxtFrm() &&
2671 				 ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
2672 				((SwTxtFrm*)pSav)->Init();	//Ich bin sein Freund.
2673 
2674 			if ( pPage && pSav->GetDrawObjs() )
2675                 ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
2676 		}
2677 		else
2678 		{	SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
2679 			if( pBlub )
2680 			{
2681 				do
2682 				{	if ( pPage && pBlub->GetDrawObjs() )
2683                         ::lcl_AddObjsToPage( pBlub, pPage );
2684 					if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
2685 				 		((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
2686 						((SwTxtFrm*)pBlub)->Init();	//Ich bin sein Freund.
2687 					pBlub = pBlub->GetNextCntntFrm();
2688 				} while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
2689 			}
2690 		}
2691 		pLast = pSav;
2692 		pSav = pSav->GetNext();
2693 
2694 	} while ( pSav );
2695 
2696 	if( pNxt )
2697 	{
2698 		pLast->pNext = pNxt;
2699 		pNxt->pPrev = pLast;
2700 	}
2701 
2702     if ( bGrow )
2703         pParent->Grow( nGrowVal );
2704 }
2705 
2706 /*************************************************************************
2707 |*
2708 |*	SqRt()				Berechnung der Quadratwurzel, damit die math.lib
2709 |*		nicht auch noch dazugelinkt werden muss.
2710 |*
2711 |*************************************************************************/
2712 
2713 sal_uLong MA_FASTCALL SqRt( BigInt nX )
2714 {
2715 	BigInt nErg = 1;
2716 
2717 	if ( !nX.IsNeg() )
2718 	{
2719 		BigInt nOldErg = 1;
2720 		for ( int i = 0; i <= 5; i++ )
2721 		{
2722 			nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
2723 			nOldErg = nErg;
2724 		}
2725 	}
2726 	return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (sal_uLong)nErg;
2727 }
2728 
2729 /*************************************************************************/
2730 
2731 SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
2732 						  sal_Bool bOdd, sal_Bool bInsertEmpty, sal_Bool bFtn,
2733 						  SwFrm *pSibling )
2734 {
2735 	SwPageFrm *pRet;
2736 	SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
2737 	SwFrmFmt *pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
2738 	//Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
2739 	//eine Leerseite einfuegen.
2740 	if ( !pFmt )
2741 	{
2742 		pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
2743 		ASSERT( pFmt, "Descriptor without any format?!" );
2744 		bInsertEmpty = !bInsertEmpty;
2745 	}
2746 	if( bInsertEmpty )
2747 	{
2748 		SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
2749 				((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
2750 		pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
2751 		pRet->Paste( pUpper, pSibling );
2752 		pRet->PreparePage( bFtn );
2753 	}
2754 	pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
2755 	pRet->Paste( pUpper, pSibling );
2756 	pRet->PreparePage( bFtn );
2757 	if ( pRet->GetNext() )
2758 		((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
2759 	return pRet;
2760 }
2761 
2762 
2763 /*************************************************************************
2764 |*
2765 |*	RegistFlys(), Regist()	Die beiden folgenden Methoden durchsuchen rekursiv
2766 |*		eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
2767 |*		innerhalb der Struktur als Anker haben bei der Seite an.
2768 |*
2769 |*************************************************************************/
2770 
2771 void MA_FASTCALL lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
2772 {
2773     SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
2774 	for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2775 	{
2776         SwAnchoredObject* pObj = (*pObjs)[i];
2777         if ( pObj->ISA(SwFlyFrm) )
2778 		{
2779             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2780 			//Ggf. ummelden, nicht anmelden wenn bereits bekannt.
2781             // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
2782             SwPageFrm *pPg = pFly->IsFlyFreeFrm()
2783                              ? pFly->GetPageFrm() : pFly->FindPageFrm();
2784 			if ( pPg != pPage )
2785 			{
2786 				if ( pPg )
2787                     pPg->RemoveFlyFromPage( pFly );
2788                 pPage->AppendFlyToPage( pFly );
2789 			}
2790 			::RegistFlys( pPage, pFly );
2791 		}
2792 		else
2793 		{
2794             // --> OD 2008-04-22 #i87493#
2795             if ( pPage != pObj->GetPageFrm() )
2796             {
2797                 // --> OD 2004-07-02 #i28701#
2798                 if ( pObj->GetPageFrm() )
2799                     pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
2800                 pPage->AppendDrawObjToPage( *pObj );
2801                 // <--
2802             }
2803             // <--
2804 		}
2805 
2806         const SwFlyFrm* pFly = pAnch->FindFlyFrm();
2807         if ( pFly &&
2808              pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
2809              pObj->GetDrawObj()->GetPage() )
2810         {
2811             pObj->DrawObj()->GetPage()->SetObjectOrdNum(
2812                                 pObj->GetDrawObj()->GetOrdNumDirect(),
2813                                 pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1 );
2814         }
2815 	}
2816 }
2817 
2818 void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
2819 {
2820 	if ( pLay->GetDrawObjs() )
2821 		::lcl_Regist( pPage, pLay );
2822 	const SwFrm *pFrm = pLay->Lower();
2823 	while ( pFrm )
2824 	{
2825 		if ( pFrm->IsLayoutFrm() )
2826 			::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
2827 		else if ( pFrm->GetDrawObjs() )
2828 			::lcl_Regist( pPage, pFrm );
2829 		pFrm = pFrm->GetNext();
2830 	}
2831 }
2832 
2833 /*************************************************************************
2834 |*
2835 |*	void Notify()
2836 |*
2837 |*	Beschreibung		Benachrichtigt den Hintergrund je nach der
2838 |*		Veraenderung zwischen altem und neuem Rechteckt.
2839 |*
2840 |*************************************************************************/
2841 
2842 void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
2843              const SwRect* pOldPrt )
2844 {
2845     const SwRect aFrm( pFly->GetObjRectWithSpaces() );
2846 	if ( rOld.Pos() != aFrm.Pos() )
2847 	{	//Positionsaenderung, alten und neuen Bereich invalidieren
2848 		if ( rOld.HasArea() &&
2849 			 rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < WEIT_WECH )
2850 		{
2851 			pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
2852 		}
2853 		pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2854 	}
2855 	else if ( rOld.SSize() != aFrm.SSize() )
2856 	{	//Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
2857 		//ueberdeckt wird invalidieren.
2858 		//Der Einfachheit halber wird hier bewusst jeweils ein Twip
2859 		//unnoetig invalidiert.
2860 
2861 		ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
2862 		if( pSh && rOld.HasArea() )
2863 			pSh->InvalidateWindows( rOld );
2864 
2865         // --> OD 2005-08-19 #i51941# - consider case that fly frame isn't
2866         // registered at the old page <pOld>
2867         SwPageFrm* pPageFrm = pFly->FindPageFrm();
2868         if ( pOld != pPageFrm )
2869         {
2870             pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
2871         }
2872         // <--
2873 
2874 		if ( rOld.Left() != aFrm.Left() )
2875         {
2876             SwRect aTmp( rOld );
2877 			aTmp.Union( aFrm );
2878 			aTmp.Left(	Min(aFrm.Left(), rOld.Left()) );
2879 			aTmp.Right( Max(aFrm.Left(), rOld.Left()) );
2880 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2881 		}
2882 		SwTwips nOld = rOld.Right();
2883 		SwTwips nNew = aFrm.Right();
2884 		if ( nOld != nNew )
2885         {
2886             SwRect aTmp( rOld );
2887 			aTmp.Union( aFrm );
2888 			aTmp.Left(	Min(nNew, nOld) );
2889 			aTmp.Right( Max(nNew, nOld) );
2890 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2891 		}
2892 		if ( rOld.Top() != aFrm.Top() )
2893         {
2894             SwRect aTmp( rOld );
2895 			aTmp.Union( aFrm );
2896 			aTmp.Top(	 Min(aFrm.Top(), rOld.Top()) );
2897 			aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) );
2898 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2899 		}
2900 		nOld = rOld.Bottom();
2901 		nNew = aFrm.Bottom();
2902 		if ( nOld != nNew )
2903         {
2904             SwRect aTmp( rOld );
2905 			aTmp.Union( aFrm );
2906 			aTmp.Top(	 Min(nNew, nOld) );
2907 			aTmp.Bottom( Max(nNew, nOld) );
2908 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2909 		}
2910 	}
2911     else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
2912               pFly->GetFmt()->GetSurround().IsContour() )
2913     {
2914         // #i24097#
2915         pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2916     }
2917 }
2918 
2919 /*************************************************************************/
2920 
2921 void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
2922 {
2923     SwTwips nBottom = rRect.Bottom();
2924     while( pFrm )
2925     {
2926         if( pFrm->IsLayoutFrm() )
2927         {
2928             if( rRect.IsOver( pFrm->Frm() ) )
2929                 lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
2930         }
2931         else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
2932         {
2933             if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
2934                 pFrm->InvalidateSize();
2935             else
2936                 pFrm->InvalidateNextPos();
2937         }
2938         pFrm = pFrm->GetNext();
2939     }
2940 }
2941 
2942 void MA_FASTCALL lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
2943 	const SwRect &rRect, const PrepareHint eHint )
2944 {
2945 	if ( pCnt->IsTxtFrm() )
2946 	{
2947 		SwRect aCntPrt( pCnt->Prt() );
2948 		aCntPrt.Pos() += pCnt->Frm().Pos();
2949 		if ( eHint == PREP_FLY_ATTR_CHG )
2950 		{
2951             // --> OD 2004-10-20 #i35640# - use given rectangle <rRect> instead
2952             // of current bound rectangle
2953             if ( aCntPrt.IsOver( rRect ) )
2954             // <--
2955 				pCnt->Prepare( PREP_FLY_ATTR_CHG );
2956 		}
2957         // --> OD 2004-11-01 #i23129# - only invalidate, if the text frame
2958         // printing area overlaps with the given rectangle.
2959         else if ( aCntPrt.IsOver( rRect ) )
2960         // <--
2961 			pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
2962 		if ( pCnt->GetDrawObjs() )
2963 		{
2964             const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
2965 			for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2966 			{
2967                 SwAnchoredObject* pObj = rObjs[i];
2968                 if ( pObj->ISA(SwFlyFrm) )
2969 				{
2970                     SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2971 					if ( pFly->IsFlyInCntFrm() )
2972 					{
2973 						SwCntntFrm *pCntnt = pFly->ContainsCntnt();
2974 						while ( pCntnt )
2975 						{
2976 							::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
2977 							pCntnt = pCntnt->GetNextCntntFrm();
2978 						}
2979 					}
2980 				}
2981 			}
2982 		}
2983 	}
2984 }
2985 
2986 void Notify_Background( const SdrObject* pObj,
2987                         SwPageFrm* pPage,
2988                         const SwRect& rRect,
2989                         const PrepareHint eHint,
2990                         const sal_Bool bInva )
2991 {
2992 
2993 	//Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
2994 	//alte Bereich nicht benachrichtigt werden.
2995 	if ( eHint == PREP_FLY_LEAVE && rRect.Top() == WEIT_WECH )
2996 		 return;
2997 
2998     SwLayoutFrm* pArea;
2999 	SwFlyFrm *pFlyFrm = 0;
3000 	SwFrm* pAnchor;
3001 	if( pObj->ISA(SwVirtFlyDrawObj) )
3002 	{
3003 		pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
3004         pAnchor = pFlyFrm->AnchorFrm();
3005 	}
3006 	else
3007 	{
3008 		pFlyFrm = NULL;
3009         pAnchor = const_cast<SwFrm*>(
3010                     GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
3011 	}
3012 	if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
3013 		pArea = pAnchor->FindFlyFrm();
3014 	else
3015         pArea = pPage;
3016 	SwCntntFrm *pCnt = 0;
3017 	if ( pArea )
3018 	{
3019         if( PREP_FLY_ARRIVE != eHint )
3020             lcl_CheckFlowBack( pArea, rRect );
3021 
3022 		//Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
3023 		//brauchen diese nicht abgeklappert werden.
3024 		//Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
3025 		//"oben" kommen.
3026 		// Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
3027 		// die gesamte Seite abgearbeitet werden. (47722)
3028         // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
3029         // on the object positioning, the complete area has to be processed,
3030         // because content frames before the anchor frame also have to consider
3031         // the object for the text wrapping.
3032         // --> OD 2004-08-25 #i3317# - The complete area has always been
3033         // processed.
3034         {
3035 			pCnt = pArea->ContainsCntnt();
3036         }
3037         // <--
3038 	}
3039 	SwFrm *pLastTab = 0;
3040 
3041     while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
3042 	{
3043 		::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
3044 		if ( pCnt->IsInTab() )
3045 		{
3046 			SwLayoutFrm* pCell = pCnt->GetUpper();
3047             // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
3048             // instead of <GetCurrentBoundRect()>, because a recalculation
3049             // of the bounding rectangle isn't intended here.
3050             if ( pCell->IsCellFrm() &&
3051                  ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
3052                    pCell->Frm().IsOver( rRect ) ) )
3053             // <--
3054 			{
3055 				const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
3056                 if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
3057 					pCell->InvalidatePrt();
3058 			}
3059 			SwTabFrm *pTab = pCnt->FindTabFrm();
3060 			if ( pTab != pLastTab )
3061 			{
3062 				pLastTab = pTab;
3063                 // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
3064                 // instead of <GetCurrentBoundRect()>, because a recalculation
3065                 // of the bounding rectangle isn't intended here.
3066                 if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
3067                      pTab->Frm().IsOver( rRect ) )
3068                 // <--
3069 				{
3070                     if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
3071 						pTab->InvalidatePrt();
3072 				}
3073 			}
3074 		}
3075 		pCnt = pCnt->GetNextCntntFrm();
3076 	}
3077 // #108745# Sorry, but this causes nothing but trouble. I remove these lines
3078 // taking the risk that the footer frame will have a wrong height
3079 //  if( pPage->Lower() )
3080 //  {
3081 //      SwFrm* pFrm = pPage->Lower();
3082 //      while( pFrm->GetNext() )
3083 //          pFrm = pFrm->GetNext();
3084 //      if( pFrm->IsFooterFrm() &&
3085 //          ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
3086 //              pFrm->Frm().IsOver( rRect ) ) ) )
3087 //           pFrm->InvalidateSize();
3088 //  }
3089     // --> OD 2007-07-24 #128702# - make code robust
3090     if ( pPage && pPage->GetSortedObjs() )
3091     // <--
3092 	{
3093 		pObj->GetOrdNum();
3094         const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3095 		for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3096 		{
3097             SwAnchoredObject* pAnchoredObj = rObjs[i];
3098             if ( pAnchoredObj->ISA(SwFlyFrm) )
3099 			{
3100                 if( pAnchoredObj->GetDrawObj() == pObj )
3101 					continue;
3102                 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3103 				if ( pFly->Frm().Top() == WEIT_WECH )
3104 					continue;
3105 
3106 				if ( !pFlyFrm ||
3107                         (!pFly->IsLowerOf( pFlyFrm ) &&
3108 						pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
3109 				{
3110 					pCnt = pFly->ContainsCntnt();
3111 					while ( pCnt )
3112 					{
3113 						::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
3114 						pCnt = pCnt->GetNextCntntFrm();
3115 					}
3116 				}
3117 				if( pFly->IsFlyLayFrm() )
3118 				{
3119 					if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
3120 						pFly->Frm().Bottom() >= rRect.Top() &&
3121 						pFly->Frm().Top() <= rRect.Bottom() &&
3122 						pFly->Frm().Right() >= rRect.Left() &&
3123 						pFly->Frm().Left() <= rRect.Right() )
3124 					 {
3125                         pFly->InvalidateSize();
3126 					 }
3127 				}
3128 				//Flys, die ueber mir liegen muessen/mussten evtl.
3129 				//ausweichen, wenn sie eine automatische Ausrichtung haben.
3130 				//das ist unabhaengig von meinem Attribut, weil dies sich
3131 				//gerade geaendert haben kann und eben deshalb
3132 				//umformatiert wurde.
3133 				else if ( pFly->IsFlyAtCntFrm() &&
3134 						pObj->GetOrdNumDirect() <
3135 						pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
3136                         pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
3137 				{
3138 					const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
3139                     if ( text::HoriOrientation::NONE != rH.GetHoriOrient()  &&
3140                             text::HoriOrientation::CENTER != rH.GetHoriOrient()  &&
3141                             ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
3142 							(pFly->Frm().Bottom() >= rRect.Top() &&
3143 							pFly->Frm().Top() <= rRect.Bottom()) )
3144 						pFly->InvalidatePos();
3145 				}
3146 			}
3147 		}
3148 	}
3149 	if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
3150 		pAnchor->GetUpper()->InvalidateSize();
3151 
3152     // --> OD 2008-01-30 #i82258# - make code robust
3153     ViewShell* pSh = 0;
3154     if ( bInva && pPage &&
3155         0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
3156     {
3157         pSh->InvalidateWindows( rRect );
3158     }
3159     // <--
3160 }
3161 
3162 /*************************************************************************
3163 |*
3164 |*	GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
3165 |*  des Ankers. Falls es sich dabei um verkettete Rahmen oder
3166 |*	Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
3167 |*
3168 |*************************************************************************/
3169 
3170 const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
3171 {
3172 	if( pFrm->IsTxtFrm() )
3173 	{
3174 		pFrm = pFrm->GetUpper();
3175 		if( !pFrm->Frm().IsInside( rPos ) )
3176 		{
3177 			if( pFrm->IsFtnFrm() )
3178 			{
3179 				const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
3180 				while( pTmp )
3181 				{
3182 					if( pTmp->Frm().IsInside( rPos ) )
3183 						return pTmp;
3184 					pTmp = pTmp->GetFollow();
3185 				}
3186 			}
3187 			else
3188 			{
3189 				SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
3190 				while( pTmp )
3191 				{
3192 					if( pTmp->Frm().IsInside( rPos ) )
3193 						return pTmp;
3194 					pTmp = pTmp->GetNextLink();
3195 				}
3196 			}
3197 		}
3198 	}
3199 	return pFrm;
3200 }
3201 
3202 /*************************************************************************/
3203 
3204 sal_Bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
3205 {
3206 	Point aPos;
3207 	const SwFrm* pFrm;
3208 	if( pObj->ISA(SwVirtFlyDrawObj) )
3209 	{
3210 		const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
3211         pFrm = pFly->GetAnchorFrm();
3212 		aPos = pFly->Frm().Pos();
3213 	}
3214 	else
3215 	{
3216         pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
3217 		aPos = pObj->GetCurrentBoundRect().TopLeft();
3218 	}
3219 	ASSERT( pFrm, "8-( Fly is lost in Space." );
3220 	pFrm = GetVirtualUpper( pFrm, aPos );
3221 	do
3222 	{	if ( pFrm == pCurrFrm )
3223 			return sal_True;
3224 		if( pFrm->IsFlyFrm() )
3225 		{
3226 			aPos = pFrm->Frm().Pos();
3227             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3228 		}
3229 		else
3230 			pFrm = pFrm->GetUpper();
3231 	} while ( pFrm );
3232 	return sal_False;
3233 }
3234 
3235 const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp )
3236 {
3237 	//Liefert die Umgebung des Frm in die kein Fly aus einer anderen
3238 	//Umgebung hineinragen kann.
3239 	const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
3240 						FRM_FTN  | FRM_FLY      |
3241 						FRM_TAB  | FRM_ROW		| FRM_CELL |
3242 						nAdditionalKontextTyp;
3243 	do
3244 	{	if ( pFrm->GetType() & nTyp )
3245 			break;
3246 		pFrm = pFrm->GetUpper();
3247 	} while( pFrm );
3248 	return pFrm;
3249 }
3250 
3251 sal_Bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
3252 {
3253 	const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
3254 
3255 	const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
3256 						FRM_FTN  | FRM_FLY      |
3257 						FRM_TAB  | FRM_ROW 		| FRM_CELL;
3258 	do
3259 	{	if ( pFrm->GetType() & nTyp )
3260 		{
3261 			if( pFrm == pKontext )
3262 				return sal_True;
3263 			if( pFrm->IsCellFrm() )
3264 				return sal_False;
3265 		}
3266 		if( pFrm->IsFlyFrm() )
3267 		{
3268 			Point aPos( pFrm->Frm().Pos() );
3269             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3270 		}
3271 		else
3272 			pFrm = pFrm->GetUpper();
3273 	} while( pFrm );
3274 
3275 	return sal_False;
3276 }
3277 
3278 
3279 //---------------------------------
3280 
3281 SwTwips MA_FASTCALL lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
3282 {
3283 	if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
3284 	{
3285 		SwFrm *pLow = pCell->Lower();
3286 		long nHeight = 0, nFlyAdd = 0;
3287 		do
3288 		{
3289 			long nLow = pLow->Frm().Height();
3290 			if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
3291 				nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
3292 			else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
3293 				nLow += ((SwSectionFrm*)pLow)->Undersize();
3294 			nFlyAdd = Max( 0L, nFlyAdd - nLow );
3295 			nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
3296 			nHeight += nLow;
3297 			pLow = pLow->GetNext();
3298 		} while ( pLow );
3299 		if ( nFlyAdd )
3300 			nHeight += nFlyAdd;
3301 
3302 		//Der Border will natuerlich auch mitspielen, er kann leider nicht
3303 		//aus PrtArea und Frm errechnet werden, da diese in beliebiger
3304 		//Kombination ungueltig sein koennen.
3305 		SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
3306 		const SwBorderAttrs &rAttrs = *aAccess.Get();
3307 		nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
3308 
3309 		return pCell->Frm().Height() - nHeight;
3310 	}
3311 	else
3312 	{
3313 		long nRstHeight = 0;
3314 		SwFrm *pLow = pCell->Lower();
3315 		do
3316 		{	nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
3317 			pLow = pLow->GetNext();
3318 
3319 		} while ( pLow );
3320 
3321 		return nRstHeight;
3322 	}
3323 }
3324 
3325 SwTwips MA_FASTCALL CalcRowRstHeight( SwLayoutFrm *pRow )
3326 {
3327 	SwTwips nRstHeight = LONG_MAX;
3328 	SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
3329 	while ( pLow )
3330 	{
3331 		nRstHeight = Min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
3332 		pLow = (SwLayoutFrm*)pLow->GetNext();
3333 	}
3334 	return nRstHeight;
3335 }
3336 
3337 const SwFrm* MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage )
3338 {
3339 	if ( !rRect.IsOver( pPage->Frm() ) )
3340 	{
3341         const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
3342         const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
3343         if ( pTmpPage )
3344             pPage = pTmpPage;
3345     }
3346 
3347     return pPage;
3348 }
3349 
3350 #include <svl/smplhint.hxx>
3351 class SwFrmHolder : private SfxListener
3352 {
3353     SwFrm* pFrm;
3354     bool bSet;
3355     virtual void Notify(  SfxBroadcaster& rBC, const SfxHint& rHint );
3356 public:
3357     SwFrmHolder() : pFrm(0), bSet(false) {}
3358     void SetFrm( SwFrm* pHold );
3359     SwFrm* GetFrm() { return pFrm; }
3360     void Reset();
3361     bool IsSet() { return bSet; }
3362 };
3363 
3364 void SwFrmHolder::SetFrm( SwFrm* pHold )
3365 {
3366     bSet = true;
3367     pFrm = pHold;
3368     StartListening(*pHold);
3369 }
3370 
3371 void SwFrmHolder::Reset()
3372 {
3373     if (pFrm)
3374         EndListening(*pFrm);
3375     bSet = false;
3376     pFrm = 0;
3377 }
3378 
3379 void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
3380 {
3381     if ( rHint.IsA(TYPE(SfxSimpleHint)) )
3382     {
3383         if ( ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_DYING && &rBC == pFrm )
3384             pFrm = 0;
3385     }
3386 }
3387 
3388 SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
3389         const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm )
3390 {
3391 	SwFrm *pMinFrm = 0, *pTmpFrm;
3392     SwFrmHolder aHolder;
3393 	SwRect aCalcRect;
3394     bool bClientIterChanged = false;
3395 
3396 	SwIterator<SwFrm,SwModify> aIter( rMod );
3397 	do {
3398 		pMinFrm = 0;
3399         aHolder.Reset();
3400         sal_uInt64 nMinDist = 0;
3401         bClientIterChanged = false;
3402 
3403 		for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
3404         {
3405 			if( pTmpFrm->GetType() & nFrmType &&
3406                 ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
3407 				(!pTmpFrm->IsFlowFrm() ||
3408 				 !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
3409 			{
3410 				if( pPoint )
3411 				{
3412                     // watch for Frm being deleted
3413                     if ( pMinFrm )
3414                         aHolder.SetFrm( pMinFrm );
3415                     else
3416                         aHolder.Reset();
3417 
3418 					if( bCalcFrm )
3419                     {
3420                         // --> OD 2005-03-04 #b6234250# - format parent Writer
3421                         // fly frame, if it isn't been formatted yet.
3422                         // Note: The Writer fly frame could be the frame itself.
3423                         SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
3424                         if ( pFlyFrm &&
3425                              pFlyFrm->Frm().Pos().X() == WEIT_WECH &&
3426                              pFlyFrm->Frm().Pos().Y() == WEIT_WECH )
3427                         {
3428                             SwObjectFormatter::FormatObj( *pFlyFrm );
3429                         }
3430                         // <--
3431                         pTmpFrm->Calc();
3432                     }
3433 
3434                     // #127369#
3435                     // aIter.IsChanged checks if the current pTmpFrm has been deleted while
3436                     // it is the current iterator
3437                     // FrmHolder watches for deletion of the current pMinFrm
3438                     if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
3439                     {
3440                         // restart iteration
3441                         bClientIterChanged = true;
3442                         break;
3443                     }
3444 
3445 					// bei Flys ggfs. ueber den Parent gehen wenn sie selbst
3446 					// nocht nicht "formatiert" sind
3447 					if( !bCalcFrm && nFrmType & FRM_FLY &&
3448                         ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
3449 						WEIT_WECH == pTmpFrm->Frm().Pos().X() &&
3450 						WEIT_WECH == pTmpFrm->Frm().Pos().Y() )
3451                         aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
3452 					else
3453 						aCalcRect = pTmpFrm->Frm();
3454 
3455                     if ( aCalcRect.IsInside( *pPoint ) )
3456                     {
3457 					    pMinFrm = pTmpFrm;
3458 						break;
3459                     }
3460 
3461                     // Point not in rectangle. Compare distances:
3462                     const Point aCalcRectCenter = aCalcRect.Center();
3463                     const Point aDiff = aCalcRectCenter - *pPoint;
3464                     const sal_uInt64 nCurrentDist = aDiff.X() * aDiff.X() + aDiff.Y() * aDiff.Y(); // opt: no sqrt
3465                     if ( !pMinFrm || nCurrentDist < nMinDist )
3466                     {
3467         				pMinFrm = pTmpFrm;
3468 	        			nMinDist = nCurrentDist;
3469                     }
3470 				}
3471 				else
3472 				{
3473 					// Wenn kein pPoint angegeben ist, dann reichen
3474 					// wir irgendeinen raus: den ersten!
3475 					pMinFrm = pTmpFrm;
3476 					break;
3477 				}
3478 			}
3479         }
3480 	} while( bClientIterChanged );
3481 
3482 	if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
3483 		return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
3484 
3485 	return pMinFrm;
3486 }
3487 
3488 sal_Bool IsExtraData( const SwDoc *pDoc )
3489 {
3490 	const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
3491 	return rInf.IsPaintLineNumbers() ||
3492 		   rInf.IsCountInFlys() ||
3493            ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
3494 			pDoc->GetRedlineTbl().Count());
3495 }
3496 
3497 // OD 22.09.2003 #110978#
3498 const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
3499 {
3500     SwRect aPrtWithoutHeaderFooter( Prt() );
3501     aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
3502 
3503     const SwFrm* pLowerFrm = Lower();
3504     while ( pLowerFrm )
3505     {
3506         // Note: independent on text direction page header and page footer are
3507         //       always at top respectively at bottom of the page frame.
3508         if ( pLowerFrm->IsHeaderFrm() )
3509         {
3510             aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
3511                                          pLowerFrm->Frm().Height() );
3512         }
3513         if ( pLowerFrm->IsFooterFrm() )
3514         {
3515             aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
3516                                             pLowerFrm->Frm().Height() );
3517         }
3518 
3519         pLowerFrm = pLowerFrm->GetNext();
3520     }
3521 
3522     return aPrtWithoutHeaderFooter;
3523 }
3524 
3525 /** method to determine the spacing values of a frame
3526 
3527     OD 2004-03-10 #i28701#
3528     OD 2009-08-28 #i102458#
3529     Add output parameter <obIsLineSpacingProportional>
3530 
3531     @author OD
3532 */
3533 void GetSpacingValuesOfFrm( const SwFrm& rFrm,
3534                             SwTwips& onLowerSpacing,
3535                             SwTwips& onLineSpacing,
3536                             bool& obIsLineSpacingProportional )
3537 {
3538     if ( !rFrm.IsFlowFrm() )
3539     {
3540         onLowerSpacing = 0;
3541         onLineSpacing = 0;
3542     }
3543     else
3544     {
3545         const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
3546         onLowerSpacing = rULSpace.GetLower();
3547 
3548         onLineSpacing = 0;
3549         obIsLineSpacingProportional = false;
3550         if ( rFrm.IsTxtFrm() )
3551         {
3552             onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
3553             obIsLineSpacingProportional =
3554                 onLineSpacing != 0 &&
3555                 static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
3556         }
3557 
3558         ASSERT( onLowerSpacing >= 0 && onLineSpacing >= 0,
3559                 "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
3560     }
3561 }
3562 
3563 /** method to get the content of the table cell, skipping content from nested tables
3564 */
3565 const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
3566 {
3567     const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
3568     const SwTabFrm* pTab = rCell.FindTabFrm();
3569 
3570     while ( pCntnt && rCell.IsAnLower( pCntnt ) )
3571     {
3572         const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
3573         if ( pTmpTab != pTab )
3574         {
3575             pCntnt = pTmpTab->FindLastCntnt();
3576             if ( pCntnt )
3577 
3578                 pCntnt = pCntnt->FindNextCnt();
3579 
3580         }
3581         else
3582             break;
3583     }
3584     return pCntnt;
3585 }
3586 
3587 /** Can be used to check if a frame has been deleted
3588  */
3589 bool SwDeletionChecker::HasBeenDeleted()
3590 {
3591     if ( !mpFrm || !mpRegIn )
3592         return false;
3593 
3594     SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
3595     SwFrm* pLast = aIter.First();
3596     while ( pLast )
3597     {
3598         if ( pLast == mpFrm )
3599             return false;
3600         pLast = aIter.Next();
3601     }
3602 
3603     return true;
3604 }
3605 
3606 
3607