xref: /aoo42x/main/sw/source/core/layout/layact.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 
31 
32 
33 #include <time.h>
34 #include "rootfrm.hxx"
35 #include "pagefrm.hxx"
36 #include "cntfrm.hxx"
37 #include "doc.hxx"
38 #include "IDocumentDrawModelAccess.hxx"
39 #include "IDocumentSettingAccess.hxx"
40 #include "IDocumentLayoutAccess.hxx"
41 #include "IDocumentStatistics.hxx"
42 #include "IDocumentTimerAccess.hxx"
43 #include "viewimp.hxx"
44 #include "crsrsh.hxx"
45 #include "dflyobj.hxx"
46 #include "flyfrm.hxx"
47 #include "frmtool.hxx"
48 #include "dcontact.hxx"
49 #include "ndtxt.hxx"    // OnlineSpelling
50 #include "frmfmt.hxx"
51 #include "swregion.hxx"
52 #include "viewopt.hxx"  // OnlineSpelling ueber Internal-TabPage testen.
53 #include "pam.hxx"		// OnlineSpelling wg. der aktuellen Cursorposition
54 #include "dbg_lay.hxx"
55 #include "layouter.hxx" // LoopControlling
56 #include "docstat.hxx"
57 #include "swevent.hxx"
58 
59 #include <sfx2/event.hxx>
60 
61 #include <ftnidx.hxx>
62 #include <vcl/window.hxx>
63 #include <vcl/svapp.hxx>
64 #include <editeng/opaqitem.hxx>
65 #include <editeng/brshitem.hxx>
66 #include <SwSmartTagMgr.hxx>
67 
68 #define _SVSTDARR_BOOLS
69 #include <svl/svstdarr.hxx>
70 
71 #define _LAYACT_CXX
72 #include "layact.hxx"
73 #include <swwait.hxx>
74 #include <fmtsrnd.hxx>
75 #include <fmtanchr.hxx>
76 #include <tools/shl.hxx>
77 #include <sfx2/progress.hxx>
78 #ifndef _DOCSH_HXX
79 #include <docsh.hxx>
80 #endif
81 
82 #include "swmodule.hxx"
83 #include "fmtline.hxx"
84 #include "tabfrm.hxx"
85 #include "ftnfrm.hxx"
86 #include "txtfrm.hxx"
87 #include "notxtfrm.hxx"
88 #include "flyfrms.hxx"
89 #include "mdiexp.hxx"
90 #include "fmtornt.hxx"
91 #include "sectfrm.hxx"
92 #include "lineinfo.hxx"
93 #include <acmplwrd.hxx>
94 // --> OD 2004-06-28 #i28701#
95 #include <sortedobjs.hxx>
96 #include <objectformatter.hxx>
97 #include <PostItMgr.hxx>
98 
99 // <--
100 //#pragma optimize("ity",on)
101 
102 /*************************************************************************
103 |*
104 |*	SwLayAction Statisches Geraffel
105 |*
106 |*	Ersterstellung		MA 22. Dec. 93
107 |*	Letzte Aenderung	MA 22. Dec. 93
108 |*
109 |*************************************************************************/
110 
111 #define IS_FLYS (pPage->GetSortedObjs())
112 #define IS_INVAFLY (pPage->IsInvalidFly())
113 
114 
115 //Sparen von Schreibarbeit um den Zugriff auf zerstoerte Seiten zu vermeiden.
116 #ifdef DBG_UTIL
117 
118 static void BreakPoint()
119 {
120 	return;
121 }
122 
123 #define CHECKPAGE \
124 			{	if ( IsAgain() ) \
125 				{	BreakPoint(); \
126 					return; \
127 				} \
128 			}
129 
130 #define XCHECKPAGE \
131 			{	if ( IsAgain() ) \
132 				{	BreakPoint(); \
133 					if( bNoLoop ) \
134 						pLayoutAccess->GetLayouter()->EndLoopControl(); \
135 					return; \
136 				} \
137 			}
138 #else
139 #define CHECKPAGE \
140 			{	if ( IsAgain() ) \
141 					return; \
142 			}
143 
144 #define XCHECKPAGE \
145 			{	if ( IsAgain() ) \
146 				{ \
147 					if( bNoLoop ) \
148 						pLayoutAccess->GetLayouter()->EndLoopControl(); \
149 					return; \
150 				} \
151 			}
152 #endif
153 
154 #define RESCHEDULE \
155 	{ \
156 		if ( IsReschedule() )  \
157         { \
158             if (pProgress) pProgress->Reschedule(); \
159 			::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \
160         } \
161 	}
162 
163 inline sal_uLong Ticks()
164 {
165 	return 1000 * clock() / CLOCKS_PER_SEC;
166 }
167 
168 void SwLayAction::CheckWaitCrsr()
169 {
170 	RESCHEDULE
171 	if ( !IsWait() && IsWaitAllowed() && IsPaint() &&
172 		 ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC/2) )
173 	{
174 		pWait = new SwWait( *pRoot->GetFmt()->GetDoc()->GetDocShell(), sal_True );
175 	}
176 }
177 
178 /*************************************************************************
179 |*
180 |*	SwLayAction::CheckIdleEnd()
181 |*
182 |*	Ersterstellung		MA 12. Aug. 94
183 |*	Letzte Aenderung	MA 24. Jun. 96
184 |*
185 |*************************************************************************/
186 //Ist es wirklich schon soweit...
187 inline void SwLayAction::CheckIdleEnd()
188 {
189     if ( !IsInput() )
190         bInput = GetInputType() && Application::AnyInput( GetInputType() );
191 }
192 
193 /*************************************************************************
194 |*
195 |*	SwLayAction::SetStatBar()
196 |*
197 |*	Ersterstellung		MA 10. Aug. 94
198 |*	Letzte Aenderung	MA 06. Aug. 95
199 |*
200 |*************************************************************************/
201 void SwLayAction::SetStatBar( sal_Bool bNew )
202 {
203 	if ( bNew )
204 	{
205 		nEndPage = pRoot->GetPageNum();
206 		nEndPage += nEndPage * 10 / 100;
207 	}
208 	else
209 		nEndPage = USHRT_MAX;
210 }
211 
212 /*************************************************************************
213 |*
214 |*	SwLayAction::PaintCntnt()
215 |*
216 |* 	Beschreibung		Je nach Typ wird der Cntnt entsprechend seinen
217 |* 		Veraenderungen ausgegeben bzw. wird die auszugebende Flaeche in der
218 |* 		Region eingetragen.
219 |* 		PaintCntnt:  fuellt die Region,
220 |*	Ersterstellung		BP 19. Jan. 92
221 |*	Letzte Aenderung	MA 10. Sep. 96
222 |*
223 |*************************************************************************/
224 sal_Bool SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt,
225 									const SwPageFrm *pPage )
226 {
227 	SwRegionRects aTmp( rRect );
228     const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
229 	const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm();
230 	sal_uInt16 i;
231 
232 	for ( i = 0; i < rObjs.Count() && aTmp.Count(); ++i )
233 	{
234         SdrObject *pO = rObjs[i]->DrawObj();
235 		if ( !pO->ISA(SwVirtFlyDrawObj) )
236 			continue;
237 
238         // OD 2004-01-15 #110582# - do not consider invisible objects
239         const IDocumentDrawModelAccess* pIDDMA = pPage->GetFmt()->getIDocumentDrawModelAccess();
240         if ( !pIDDMA->IsVisibleLayerId( pO->GetLayer() ) )
241         {
242             continue;
243         }
244 
245         SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
246 
247 		if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) )
248 			continue;
249 
250         if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
251 			continue;
252 
253         if ( pFly->GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() )
254 			continue;
255 
256 		if ( pSelfFly )
257 		{
258 			const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
259 			if ( pO->GetLayer() == pTmp->GetLayer() )
260 			{
261 				if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
262 					//Im gleichen Layer werden nur obenliegende beachtet.
263 					continue;
264 			}
265 			else
266 			{
267                 const sal_Bool bLowerOfSelf = pFly->IsLowerOf( pSelfFly );
268 				if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
269 					//Aus anderem Layer interessieren uns nur nicht transparente
270 					//oder innenliegende
271 					continue;
272 			}
273 		}
274 
275         /// OD 19.08.2002 #99657#
276         ///     Fly frame without a lower have to be subtracted from paint region.
277         ///     For checking, if fly frame contains transparent graphic or
278         ///     has surrounded contour, assure that fly frame has a lower
279         if ( pFly->Lower() &&
280              pFly->Lower()->IsNoTxtFrm() &&
281              ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
282                pFly->GetFmt()->GetSurround().IsContour() )
283            )
284 		{
285 			continue;
286 		}
287 
288         /// OD 19.08.2002 #99657#
289         ///     Region of a fly frame with transparent background or a transparent
290         ///     shadow have not to be subtracted from paint region
291         if ( pFly->IsBackgroundTransparent() ||
292              pFly->IsShadowTransparent() )
293         {
294             continue;
295         }
296 
297 		aTmp -= pFly->Frm();
298 	}
299 
300     sal_Bool bRetPaint = sal_False;
301 	const SwRect *pData = aTmp.GetData();
302 	for ( i = 0; i < aTmp.Count(); ++pData, ++i )
303         bRetPaint |= pImp->GetShell()->AddPaintRect( *pData );
304     return bRetPaint;
305 }
306 
307 inline sal_Bool SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt,
308 									  const SwPageFrm *pPage,
309 									  const SwRect &rRect )
310 {
311 	if ( rRect.HasArea() )
312 	{
313 		if ( pPage->GetSortedObjs() )
314 			return PaintWithoutFlys( rRect, pCntnt, pPage );
315 		else
316 			return pImp->GetShell()->AddPaintRect( rRect );
317 	}
318 	return sal_False;
319 }
320 
321 void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt,
322 							  const SwPageFrm *pPage,
323                               const SwRect &rOldRect,
324                               long nOldBottom )
325 {
326     SWRECTFN( pCnt )
327 
328     if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() )
329 	{
330 		SwRect aPaint( pCnt->PaintArea() );
331 		if ( !_PaintCntnt( pCnt, pPage, aPaint ) )
332 			pCnt->ResetCompletePaint();
333 	}
334 	else
335 	{
336         // paint the area between printing bottom and frame bottom and
337         // the area left and right beside the frame, if its height changed.
338         long nOldHeight = (rOldRect.*fnRect->fnGetHeight)();
339         long nNewHeight = (pCnt->Frm().*fnRect->fnGetHeight)();
340         const bool bHeightDiff = nOldHeight != nNewHeight;
341         if( bHeightDiff )
342         {
343             // OD 05.11.2002 #94454# - consider whole potential paint area.
344             //SwRect aDrawRect( pCnt->UnionFrm( sal_True ) );
345             SwRect aDrawRect( pCnt->PaintArea() );
346             if( nOldHeight > nNewHeight )
347                 nOldBottom = (pCnt->*fnRect->fnGetPrtBottom)();
348             (aDrawRect.*fnRect->fnSetTop)( nOldBottom );
349             _PaintCntnt( pCnt, pPage, aDrawRect );
350         }
351         // paint content area
352         SwRect aPaintRect = static_cast<SwTxtFrm*>(const_cast<SwCntntFrm*>(pCnt))->Paint();
353         _PaintCntnt( pCnt, pPage, aPaintRect );
354 	}
355 
356 	if ( pCnt->IsRetouche() && !pCnt->GetNext() )
357 	{
358 		const SwFrm *pTmp = pCnt;
359 		if( pCnt->IsInSct() )
360 		{
361 			const SwSectionFrm* pSct = pCnt->FindSctFrm();
362 			if( pSct->IsRetouche() && !pSct->GetNext() )
363 				pTmp = pSct;
364 		}
365 		SwRect aRect( pTmp->GetUpper()->PaintArea() );
366         (aRect.*fnRect->fnSetTop)( (pTmp->*fnRect->fnGetPrtBottom)() );
367 		if ( !_PaintCntnt( pCnt, pPage, aRect ) )
368 			pCnt->ResetRetouche();
369 	}
370 }
371 
372 /*************************************************************************
373 |*
374 |*	SwLayAction::SwLayAction()
375 |*
376 |*	Ersterstellung		MA 30. Oct. 92
377 |*	Letzte Aenderung	MA 09. Jun. 95
378 |*
379 |*************************************************************************/
380 SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) :
381 	pRoot( pRt ),
382 	pImp( pI ),
383 	pOptTab( 0 ),
384 	pWait( 0 ),
385     pProgress(NULL),
386     nPreInvaPage( USHRT_MAX ),
387     nStartTicks( Ticks() ),
388     nInputType( 0 ),
389     nEndPage( USHRT_MAX ),
390     nCheckPageNum( USHRT_MAX )
391 {
392 	bPaintExtraData = ::IsExtraData( pImp->GetShell()->GetDoc() );
393 	bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True;
394 	bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
395 	bUpdateExpFlds = bBrowseActionStop = bActionInProgress = sal_False;
396     // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>.
397     mbFormatCntntOnInterrupt = sal_False;
398 
399     pImp->pLayAct = this;   //Anmelden
400 }
401 
402 SwLayAction::~SwLayAction()
403 {
404 	ASSERT( !pWait, "Wait object not destroyed" );
405 	pImp->pLayAct = 0;		//Abmelden
406 }
407 
408 /*************************************************************************
409 |*
410 |*	SwLayAction::Reset()
411 |*
412 |*	Ersterstellung		MA 11. Aug. 94
413 |*	Letzte Aenderung	MA 09. Jun. 95
414 |*
415 |*************************************************************************/
416 void SwLayAction::Reset()
417 {
418 	pOptTab = 0;
419 	nStartTicks = Ticks();
420 	nInputType = 0;
421 	nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX;
422 	bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True;
423 	bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
424 	bUpdateExpFlds = bBrowseActionStop = sal_False;
425 }
426 
427 /*************************************************************************
428 |*
429 |*	SwLayAction::RemoveEmptyBrowserPages()
430 |*
431 |*	Ersterstellung		MA 10. Sep. 97
432 |*	Letzte Aenderung	MA 10. Sep. 97
433 |*
434 |*************************************************************************/
435 
436 sal_Bool SwLayAction::RemoveEmptyBrowserPages()
437 {
438 	//Beim umschalten vom normalen in den Browsermodus bleiben u.U. einige
439 	//unangenehm lange stehen. Diese beseiten wir mal schnell.
440 	sal_Bool bRet = sal_False;
441     const ViewShell *pSh = pRoot->GetCurrShell();
442     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
443 	{
444 		SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
445 		do
446 		{
447 			if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) ||
448 				 pPage->ContainsCntnt() )
449 				pPage = (SwPageFrm*)pPage->GetNext();
450 			else
451 			{
452 				bRet = sal_True;
453 				SwPageFrm *pDel = pPage;
454 				pPage = (SwPageFrm*)pPage->GetNext();
455 				pDel->Cut();
456 				delete pDel;
457 			}
458 		} while ( pPage );
459 	}
460 	return bRet;
461 }
462 
463 
464 /*************************************************************************
465 |*
466 |*	SwLayAction::Action()
467 |*
468 |*	Ersterstellung		MA 10. Aug. 94
469 |*	Letzte Aenderung	MA 06. Aug. 95
470 |*
471 |*************************************************************************/
472 void SwLayAction::Action()
473 {
474 	bActionInProgress = sal_True;
475 
476     //TurboMode? Disqualifiziert fuer Idle-Format.
477 	if ( IsPaint() && !IsIdle() && TurboAction() )
478 	{
479 		delete pWait, pWait = 0;
480 		pRoot->ResetTurboFlag();
481 		bActionInProgress = sal_False;
482 		pRoot->DeleteEmptySct();
483         return;
484 	}
485 	else if ( pRoot->GetTurbo() )
486 	{
487 		pRoot->DisallowTurbo();
488 		const SwFrm *pFrm = pRoot->GetTurbo();
489 		pRoot->ResetTurbo();
490 		pFrm->InvalidatePage();
491 	}
492 	pRoot->DisallowTurbo();
493 
494 	if ( IsCalcLayout() )
495 		SetCheckPages( sal_False );
496 
497 	InternalAction();
498 	bAgain |= RemoveEmptyBrowserPages();
499 	while ( IsAgain() )
500 	{
501 		bAgain = bNextCycle = sal_False;
502 		InternalAction();
503 		bAgain |= RemoveEmptyBrowserPages();
504 	}
505 	pRoot->DeleteEmptySct();
506 
507 	delete pWait, pWait = 0;
508 
509 	//Turbo-Action ist auf jedenfall wieder erlaubt.
510 	pRoot->ResetTurboFlag();
511 	pRoot->ResetTurbo();
512 
513 	SetCheckPages( sal_True );
514 
515     bActionInProgress = sal_False;
516 }
517 
518 SwPageFrm* SwLayAction::CheckFirstVisPage( SwPageFrm *pPage )
519 {
520 	SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt();
521 	SwCntntFrm *pChk = pCnt;
522 	sal_Bool bPageChgd = sal_False;
523 	while ( pCnt && pCnt->IsFollow() )
524 		pCnt = static_cast<SwCntntFrm*>(pCnt)->FindMaster();
525 	if ( pCnt && pChk != pCnt )
526 	{	bPageChgd = sal_True;
527 		pPage = pCnt->FindPageFrm();
528 	}
529 
530 	if ( pPage->GetFmt()->GetDoc()->GetFtnIdxs().Count() )
531 	{
532 		SwFtnContFrm *pCont = pPage->FindFtnCont();
533 		if ( pCont )
534 		{
535 			pCnt = pCont->ContainsCntnt();
536 			pChk = pCnt;
537 			while ( pCnt && pCnt->IsFollow() )
538 				pCnt = (SwCntntFrm*)pCnt->FindPrev();
539 			if ( pCnt && pCnt != pChk )
540 			{
541 				if ( bPageChgd )
542 				{
543 					//Die 'oberste' Seite benutzten.
544 					SwPageFrm *pTmp = pCnt->FindPageFrm();
545 					if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() )
546 						pPage = pTmp;
547 				}
548 				else
549 					pPage = pCnt->FindPageFrm();
550 			}
551 		}
552 	}
553 	return pPage;
554 }
555 
556 // OD 2004-05-12 #i28701#
557 // --> OD 2004-11-03 #i114798# - unlock position on start and end of page
558 // layout process.
559 class NotifyLayoutOfPageInProgress
560 {
561     private:
562         SwPageFrm& mrPageFrm;
563 
564         void _UnlockPositionOfObjs()
565         {
566             SwSortedObjs* pObjs = mrPageFrm.GetSortedObjs();
567             if ( pObjs )
568             {
569                 sal_uInt32 i = 0;
570                 for ( ; i < pObjs->Count(); ++i )
571                 {
572                     SwAnchoredObject* pObj = (*pObjs)[i];
573                     pObj->UnlockPosition();
574                 }
575             }
576         }
577     public:
578         NotifyLayoutOfPageInProgress( SwPageFrm& _rPageFrm )
579             : mrPageFrm( _rPageFrm )
580         {
581             _UnlockPositionOfObjs();
582             _rPageFrm.SetLayoutInProgress( true );
583         }
584         ~NotifyLayoutOfPageInProgress()
585         {
586             mrPageFrm.SetLayoutInProgress( false );
587             _UnlockPositionOfObjs();
588         }
589 };
590 // <--
591 
592 void SwLayAction::InternalAction()
593 {
594     ASSERT( pRoot->Lower()->IsPageFrm(), ":-( Keine Seite unterhalb der Root.");
595 
596     pRoot->Calc();
597 
598 	//Die erste ungueltige bzw. zu formatierende Seite ermitteln.
599 	//Bei einer Complete-Action ist es die erste ungueltige; mithin ist die
600 	//erste zu formatierende Seite diejenige Seite mit der Numemr eins.
601 	//Bei einer Luegen-Formatierung ist die Nummer der erste Seite die Nummer
602 	//der ersten Sichtbaren Seite.
603 	SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() :
604 				pImp->GetFirstVisPage();
605 	if ( !pPage )
606 		pPage = (SwPageFrm*)pRoot->Lower();
607 
608 	//Wenn ein "Erster-Fliess-Cntnt" innerhalb der der ersten sichtbaren Seite
609 	//ein Follow ist, so schalten wir die Seite zurueck auf den Ur-Master dieses
610 	//Cntnt's
611 	if ( !IsComplete() )
612 		pPage = CheckFirstVisPage( pPage );
613 	sal_uInt16 nFirstPageNum = pPage->GetPhyPageNum();
614 
615 	while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
616 		pPage = (SwPageFrm*)pPage->GetNext();
617 
618     IDocumentLayoutAccess *pLayoutAccess = pRoot->GetFmt()->getIDocumentLayoutAccess();
619     sal_Bool bNoLoop = pPage ? SwLayouter::StartLoopControl( pRoot->GetFmt()->GetDoc(), pPage ) : sal_False;
620 	sal_uInt16 nPercentPageNum = 0;
621 	while ( (pPage && !IsInterrupt()) || nCheckPageNum != USHRT_MAX )
622 	{
623 		if ( !pPage && nCheckPageNum != USHRT_MAX &&
624 			 (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) )
625 		{
626 			if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum )
627 			{
628 				SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
629 				while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum )
630 					pPg = (SwPageFrm*)pPg->GetNext();
631 				if ( pPg )
632 					pPage = pPg;
633 				if ( !pPage )
634 					break;
635 			}
636 			SwPageFrm *pTmp = pPage->GetPrev() ?
637 										(SwPageFrm*)pPage->GetPrev() : pPage;
638 			SetCheckPages( sal_True );
639 			SwFrm::CheckPageDescs( pPage );
640 			SetCheckPages( sal_False );
641 			nCheckPageNum = USHRT_MAX;
642 			pPage = pTmp;
643 			continue;
644 		}
645 
646 		if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum )
647 		{
648 			nPercentPageNum = pPage->GetPhyPageNum();
649 			::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell());
650 		}
651 		pOptTab = 0;
652 			 //Kein ShortCut fuer Idle oder CalcLayout
653 		if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) )
654 		{
655 			pRoot->DeleteEmptySct();
656 			XCHECKPAGE;
657 			if ( !IsInterrupt() &&
658 				 (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
659 			{
660 				if ( pRoot->IsAssertFlyPages() )
661 					pRoot->AssertFlyPages();
662 				if ( pRoot->IsSuperfluous() )
663 				{
664 					sal_Bool bOld = IsAgain();
665 					pRoot->RemoveSuperfluous();
666 					bAgain = bOld;
667 				}
668 				if ( IsAgain() )
669 				{
670 					if( bNoLoop )
671 						pLayoutAccess->GetLayouter()->EndLoopControl();
672 					return;
673 				}
674 				pPage = (SwPageFrm*)pRoot->Lower();
675 				while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
676 					pPage = (SwPageFrm*)pPage->GetNext();
677 				while ( pPage && pPage->GetNext() &&
678 						pPage->GetPhyPageNum() < nFirstPageNum )
679 					pPage = (SwPageFrm*)pPage->GetNext();
680 				continue;
681 			}
682 			break;
683 		}
684 		else
685 		{
686 			pRoot->DeleteEmptySct();
687 			XCHECKPAGE;
688 
689             // OD 2004-05-12 #i28701# - scope for instance of class
690             // <NotifyLayoutOfPageInProgress>
691             {
692                 NotifyLayoutOfPageInProgress aLayoutOfPageInProgress( *pPage );
693 
694                 while ( !IsInterrupt() && !IsNextCycle() &&
695                         ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) )
696                 {
697                     // OD 2004-05-10 #i28701#
698                     SwObjectFormatter::FormatObjsAtFrm( *pPage, *pPage, this );
699                     if ( !IS_FLYS )
700                     {
701                         //Wenn keine Flys (mehr) da sind, sind die Flags
702                         //mehr als fluessig.
703                         pPage->ValidateFlyLayout();
704                         pPage->ValidateFlyCntnt();
705                     }
706                     // OD 2004-05-10 #i28701# - change condition
707                     while ( !IsInterrupt() && !IsNextCycle() &&
708                             ( pPage->IsInvalid() ||
709                               (IS_FLYS && IS_INVAFLY) ) )
710                     {
711                         PROTOCOL( pPage, PROT_FILE_INIT, 0, 0)
712                         XCHECKPAGE;
713 
714                         // FME 2007-08-30 #i81146# new loop control
715                         sal_uInt16 nLoopControlRuns_1 = 0;
716                         const sal_uInt16 nLoopControlMax = 20;
717 
718                         while ( !IsNextCycle() && pPage->IsInvalidLayout() )
719                         {
720                             pPage->ValidateLayout();
721 
722                             if ( ++nLoopControlRuns_1 > nLoopControlMax )
723                             {
724 #if OSL_DEBUG_LEVEL > 1
725                                 ASSERT( false, "LoopControl_1 in SwLayAction::InternalAction" )
726 #endif
727                                 break;
728                             }
729 
730                             FormatLayout( pPage );
731                             XCHECKPAGE;
732                         }
733                         // OD 2004-05-10 #i28701# - change condition
734                         if ( !IsNextCycle() &&
735                              ( pPage->IsInvalidCntnt() ||
736                                (IS_FLYS && IS_INVAFLY) ) )
737                         {
738                             pPage->ValidateFlyInCnt();
739                             pPage->ValidateCntnt();
740                             // --> OD 2004-05-10 #i28701#
741                             pPage->ValidateFlyLayout();
742                             pPage->ValidateFlyCntnt();
743                             // <--
744                             if ( !FormatCntnt( pPage ) )
745                             {
746                                 XCHECKPAGE;
747                                 pPage->InvalidateCntnt();
748                                 pPage->InvalidateFlyInCnt();
749                                 // --> OD 2004-05-10 #i28701#
750                                 pPage->InvalidateFlyLayout();
751                                 pPage->InvalidateFlyCntnt();
752                                 // <--
753                                 if ( IsBrowseActionStop() )
754                                     bInput = sal_True;
755                             }
756                         }
757                         if( bNoLoop )
758                             pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
759                     }
760                 }
761             } // end of scope for instance of class <NotifyLayoutOfPageInProgress>
762 
763 
764             //Eine vorige Seite kann wieder invalid sein.
765 			XCHECKPAGE;
766 			if ( !IS_FLYS )
767 			{
768 				//Wenn keine Flys (mehr) da sind, sind die Flags
769 				//mehr als fluessig.
770 				pPage->ValidateFlyLayout();
771 				pPage->ValidateFlyCntnt();
772 			}
773 			if ( !IsInterrupt() )
774 			{
775 				SetNextCycle( sal_False );
776 
777 				if ( nPreInvaPage != USHRT_MAX )
778 				{
779 					if( !IsComplete() && nPreInvaPage + 2 < nFirstPageNum )
780 					{
781 						pImp->SetFirstVisPageInvalid();
782 						SwPageFrm *pTmpPage = pImp->GetFirstVisPage();
783 						nFirstPageNum = pTmpPage->GetPhyPageNum();
784 						if( nPreInvaPage < nFirstPageNum )
785 						{
786 							nPreInvaPage = nFirstPageNum;
787 							pPage = pTmpPage;
788 						}
789 					}
790 					while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage )
791 						pPage = (SwPageFrm*)pPage->GetPrev();
792 					nPreInvaPage = USHRT_MAX;
793 				}
794 
795                 while ( pPage->GetPrev() &&
796 						( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() ||
797 						  ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() &&
798 							((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) &&
799 						(((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >=
800 							nFirstPageNum) )
801 				{
802 					pPage = (SwPageFrm*)pPage->GetPrev();
803                 }
804 
805                 //Weiter bis zur naechsten invaliden Seite.
806 				while ( pPage && !pPage->IsInvalid() &&
807 						(!IS_FLYS || !IS_INVAFLY) )
808 				{
809 					pPage = (SwPageFrm*)pPage->GetNext();
810 				}
811 				if( bNoLoop )
812 					pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
813 			}
814             CheckIdleEnd();
815 		}
816 		if ( !pPage && !IsInterrupt() &&
817 			 (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
818 		{
819 			if ( pRoot->IsAssertFlyPages() )
820 				pRoot->AssertFlyPages();
821 			if ( pRoot->IsSuperfluous() )
822 			{
823 				sal_Bool bOld = IsAgain();
824 				pRoot->RemoveSuperfluous();
825 				bAgain = bOld;
826 			}
827 			if ( IsAgain() )
828 			{
829 				if( bNoLoop )
830 					pLayoutAccess->GetLayouter()->EndLoopControl();
831 				return;
832 			}
833 			pPage = (SwPageFrm*)pRoot->Lower();
834 			while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
835 				pPage = (SwPageFrm*)pPage->GetNext();
836 			while ( pPage && pPage->GetNext() &&
837 					pPage->GetPhyPageNum() < nFirstPageNum )
838 				pPage = (SwPageFrm*)pPage->GetNext();
839 		}
840 	}
841 	if ( IsInterrupt() && pPage )
842 	{
843 		//Wenn ein Input anliegt wollen wir keinen Inhalt mehr Formatieren,
844 		//Das Layout muessen wir aber schon in Ordnung bringen.
845 		//Andernfalls kann folgende Situation auftreten (Bug: 3244):
846 		//Am Ende des Absatz der letzten Seite wird Text eingegeben, so das
847 		//der Absatz einen Follow fuer die nachste Seite erzeugt, ausserdem
848 		//wird gleich schnell weitergetippt - Es liegt waehrend der
849 		//Verarbeitung ein Input an. Der Absatz auf der neuen Seite wurde
850 		//bereits anformatiert, die neue Seite ist Formatiert und steht
851 		//auf CompletePaint, hat sich aber noch nicht im Auszugebenden Bereich
852 		//eingetragen. Es wird gepaintet, das CompletePaint der Seite wird
853 		//zurueckgesetzt weil der neue Absatz sich bereits eingetragen hatte,
854 		//aber die Raender der Seite werden nicht gepaintet. Naja, bei der
855 		//zwangslaeufig auftretenden naechsten LayAction traegt sich die Seite
856 		//nicht mehr ein, weil ihre (LayoutFrm-)Flags bereits zurueckgesetzt
857 		//wurden -- Der Rand der Seite wird nie gepaintet.
858 		SwPageFrm *pPg = pPage;
859 		XCHECKPAGE;
860 		const SwRect &rVis = pImp->GetShell()->VisArea();
861 
862         while( pPg && pPg->Frm().Bottom() < rVis.Top() )
863 			pPg = (SwPageFrm*)pPg->GetNext();
864         if( pPg != pPage )
865             pPg = pPg ? (SwPageFrm*)pPg->GetPrev() : pPage;
866 
867         // OD 14.04.2003 #106346# - set flag for interrupt content formatting
868         mbFormatCntntOnInterrupt = IsInput() && !IsStopPrt();
869         long nBottom = rVis.Bottom();
870         // --> OD 2005-02-15 #i42586# - format current page, if idle action is active
871         // This is an optimization for the case that the interrupt is created by
872         // the move of a form control object, which is represented by a window.
873         while ( pPg && ( pPg->Frm().Top() < nBottom ||
874                          ( IsIdle() && pPg == pPage ) ) )
875         // <--
876 		{
877             // --> OD 2004-10-11 #i26945# - follow-up of #i28701#
878             NotifyLayoutOfPageInProgress aLayoutOfPageInProgress( *pPg );
879 
880             XCHECKPAGE;
881 
882             // FME 2007-08-30 #i81146# new loop control
883             sal_uInt16 nLoopControlRuns_2 = 0;
884             const sal_uInt16 nLoopControlMax = 20;
885 
886             // OD 14.04.2003 #106346# - special case: interrupt content formatting
887             // --> OD 2004-07-08 #i28701# - conditions, introduced by #106346#,
888             // are incorrect (marcos IS_FLYS and IS_INVAFLY only works for <pPage>)
889             // and are too strict.
890             // --> OD 2005-06-09 #i50432# - adjust interrupt formatting to
891             // normal page formatting - see above.
892             while ( ( mbFormatCntntOnInterrupt &&
893                       ( pPg->IsInvalid() ||
894                         ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) ||
895                     ( !mbFormatCntntOnInterrupt && pPg->IsInvalidLayout() ) )
896             {
897                 XCHECKPAGE;
898                 // --> OD 2005-06-09 #i50432# - format also at-page anchored objects
899                 SwObjectFormatter::FormatObjsAtFrm( *pPg, *pPg, this );
900                 // <--
901                 // --> OD 2005-06-09 #i50432#
902                 if ( !pPg->GetSortedObjs() )
903                 {
904                     pPg->ValidateFlyLayout();
905                     pPg->ValidateFlyCntnt();
906                 }
907                 // <--
908 
909                 // FME 2007-08-30 #i81146# new loop control
910                 sal_uInt16 nLoopControlRuns_3 = 0;
911 
912                 while ( pPg->IsInvalidLayout() )
913                 {
914                     pPg->ValidateLayout();
915 
916                     if ( ++nLoopControlRuns_3 > nLoopControlMax )
917                     {
918 #if OSL_DEBUG_LEVEL > 1
919                         ASSERT( false, "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" )
920 #endif
921                         break;
922                     }
923 
924                     FormatLayout( pPg );
925                     XCHECKPAGE;
926                 }
927 
928                 // --> OD 2005-06-09 #i50432#
929                 if ( mbFormatCntntOnInterrupt &&
930                      ( pPg->IsInvalidCntnt() ||
931                        ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) )
932                 // <--
933                 {
934                     pPg->ValidateFlyInCnt();
935                     pPg->ValidateCntnt();
936                     // --> OD 2004-05-10 #i26945# - follow-up of fix #117736#
937                     pPg->ValidateFlyLayout();
938                     pPg->ValidateFlyCntnt();
939                     // <--
940 
941                     if ( ++nLoopControlRuns_2 > nLoopControlMax )
942                     {
943 #if OSL_DEBUG_LEVEL > 1
944                         ASSERT( false, "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" )
945 #endif
946                         break;
947                     }
948 
949                     if ( !FormatCntnt( pPg ) )
950                     {
951                         XCHECKPAGE;
952                         pPg->InvalidateCntnt();
953                         pPg->InvalidateFlyInCnt();
954                         // --> OD 2004-05-10 #i26945# - follow-up of fix #117736#
955                         pPg->InvalidateFlyLayout();
956                         pPg->InvalidateFlyCntnt();
957                         // <--
958                     }
959                     // --> OD 2005-04-06 #i46807# - we are statisfied, if the
960                     // content is formatted once complete.
961                     else
962                     {
963                         break;
964                     }
965                     // <--
966                 }
967             }
968             // <--
969 			pPg = (SwPageFrm*)pPg->GetNext();
970 		}
971         // OD 14.04.2003 #106346# - reset flag for special interrupt content formatting.
972         mbFormatCntntOnInterrupt = sal_False;
973 	}
974 	pOptTab = 0;
975 	if( bNoLoop )
976 		pLayoutAccess->GetLayouter()->EndLoopControl();
977 }
978 /*************************************************************************
979 |*
980 |*	SwLayAction::TurboAction(), _TurboAction()
981 |*
982 |*	Ersterstellung		MA 04. Dec. 92
983 |*	Letzte Aenderung	MA 15. Aug. 93
984 |*
985 |*************************************************************************/
986 sal_Bool SwLayAction::_TurboAction( const SwCntntFrm *pCnt )
987 {
988 
989 	const SwPageFrm *pPage = 0;
990 	if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() )
991 	{
992 		const SwRect aOldRect( pCnt->UnionFrm( sal_True ) );
993 		const long	 nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom();
994 		pCnt->Calc();
995 		if ( pCnt->Frm().Bottom() < aOldRect.Bottom() )
996 			pCnt->SetRetouche();
997 
998 		pPage = pCnt->FindPageFrm();
999 		PaintCntnt( pCnt, pPage, aOldRect, nOldBottom );
1000 
1001 		if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() )
1002 		{
1003 			const sal_uLong nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines();
1004 			((SwTxtFrm*)pCnt)->RecalcAllLines();
1005 			if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() )
1006 			{
1007 				if ( IsPaintExtraData() )
1008 					pImp->GetShell()->AddPaintRect( pCnt->Frm() );
1009 				//Damit die restlichen LineNums auf der Seite bereichnet werden
1010 				//und nicht hier abgebrochen wird.
1011 				//Das im RecalcAllLines zu erledigen waere teuer, weil dort
1012 				//auch in unnoetigen Faellen (normale Action) auch immer die
1013 				//Seite benachrichtigt werden muesste.
1014 				const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
1015 				while ( pNxt &&
1016 						(pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) )
1017 					pNxt = pNxt->GetNextCntntFrm();
1018 				if ( pNxt )
1019 					pNxt->InvalidatePage();
1020 			}
1021 			return sal_False;
1022 		}
1023 
1024 		if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) )
1025 			return sal_False;
1026 	}
1027 	if ( !pPage )
1028 		pPage = pCnt->FindPageFrm();
1029 
1030     // OD 2004-05-10 #i28701# - format floating screen objects at content frame.
1031     if ( pCnt->IsTxtFrm() &&
1032          !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCnt)),
1033                                               *pPage, this ) )
1034     {
1035         return sal_False;
1036     }
1037 
1038 	if ( pPage->IsInvalidCntnt() )
1039 		return sal_False;
1040 	return sal_True;
1041 }
1042 
1043 sal_Bool SwLayAction::TurboAction()
1044 {
1045 	sal_Bool bRet = sal_True;
1046 
1047 	if ( pRoot->GetTurbo() )
1048 	{
1049 		if ( !_TurboAction( pRoot->GetTurbo() ) )
1050 		{
1051 			CheckIdleEnd();
1052 			bRet = sal_False;
1053 		}
1054 		pRoot->ResetTurbo();
1055 	}
1056 	else
1057 		bRet = sal_False;
1058 	return bRet;
1059 }
1060 /*************************************************************************
1061 |*
1062 |*	SwLayAction::IsShortCut()
1063 |*
1064 |*	Beschreibung:		Liefert ein True, wenn die Seite vollstaendig unter
1065 |* 		oder rechts neben dem sichbaren Bereich liegt.
1066 |* 		Es kann passieren, dass sich die Verhaeltnisse derart aendern, dass
1067 |* 		die Verarbeitung (des Aufrufers!) mit der Vorgaengerseite der
1068 |* 		uebergebenen Seite weitergefuehrt werden muss. Der Paramter wird also
1069 |* 		ggf. veraendert!
1070 |*		Fuer den BrowseMode kann auch dann der ShortCut aktiviert werden,
1071 |*		wenn der ungueltige Inhalt der Seite unterhalb des sichbaren
1072 |*		bereiches liegt.
1073 |*	Ersterstellung		MA 30. Oct. 92
1074 |*	Letzte Aenderung	MA 18. Jul. 96
1075 |*
1076 |*************************************************************************/
1077 static bool lcl_IsInvaLay( const SwFrm *pFrm, long nBottom )
1078 {
1079 	if (
1080 	     !pFrm->IsValid() ||
1081 	     (pFrm->IsCompletePaint() && ( pFrm->Frm().Top() < nBottom ) )
1082 	   )
1083 	{
1084 		return true;
1085 	}
1086 	return false;
1087 }
1088 
1089 static const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom )
1090 {
1091 	ASSERT( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" );
1092 
1093 	if (lcl_IsInvaLay(pFrm, nBottom))
1094 		return pFrm;
1095 	pFrm = ((SwLayoutFrm*)pFrm)->Lower();
1096 	while ( pFrm )
1097 	{
1098 		if ( pFrm->IsLayoutFrm() )
1099 		{
1100 			if (lcl_IsInvaLay(pFrm, nBottom))
1101 				return pFrm;
1102 			const SwFrm *pTmp;
1103 			if ( 0 != (pTmp = lcl_FindFirstInvaLay( pFrm, nBottom )) )
1104 				return pTmp;
1105 		}
1106 		pFrm = pFrm->GetNext();
1107 	}
1108 	return 0;
1109 }
1110 
1111 static const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom,
1112 									 const SwCntntFrm *pFirst )
1113 {
1114 	const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() :
1115 									  pLay->ContainsCntnt();
1116 	while ( pCnt )
1117 	{
1118 		if ( !pCnt->IsValid() || pCnt->IsCompletePaint() )
1119 		{
1120 			if ( pCnt->Frm().Top() <= nBottom )
1121 				return pCnt;
1122 		}
1123 
1124 		if ( pCnt->GetDrawObjs() )
1125 		{
1126             const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
1127 			for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1128 			{
1129                 const SwAnchoredObject* pObj = rObjs[i];
1130                 if ( pObj->ISA(SwFlyFrm) )
1131 				{
1132                     const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
1133 					if ( pFly->IsFlyInCntFrm() )
1134 					{
1135 						if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() ||
1136 							 pFly->IsCompletePaint() )
1137 						{
1138 							if ( pFly->Frm().Top() <= nBottom )
1139 								return pFly;
1140 						}
1141 						const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 );
1142 						if ( pFrm && pFrm->Frm().Bottom() <= nBottom )
1143 							return pFrm;
1144 					}
1145 				}
1146 			}
1147 		}
1148 		if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() )
1149 			return 0;
1150 		pCnt = pCnt->GetNextCntntFrm();
1151 		if ( !pLay->IsAnLower( pCnt ) )
1152 			break;
1153 	}
1154 	return 0;
1155 }
1156 
1157 // --> OD 2005-02-21 #i37877# - consider drawing objects
1158 static const SwAnchoredObject* lcl_FindFirstInvaObj( const SwPageFrm* _pPage,
1159                                               long _nBottom )
1160 {
1161     ASSERT( _pPage->GetSortedObjs(), "FindFirstInvaObj, no Objs" )
1162 
1163     for ( sal_uInt16 i = 0; i < _pPage->GetSortedObjs()->Count(); ++i )
1164 	{
1165         const SwAnchoredObject* pObj = (*_pPage->GetSortedObjs())[i];
1166         if ( pObj->ISA(SwFlyFrm) )
1167 		{
1168             const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
1169             if ( pFly->Frm().Top() <= _nBottom )
1170 			{
1171 				if ( pFly->IsInvalid() || pFly->IsCompletePaint() )
1172 					return pFly;
1173 
1174                 const SwFrm* pTmp;
1175                 if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, _nBottom, 0 )) &&
1176                      pTmp->Frm().Top() <= _nBottom )
1177                     return pFly;
1178 			}
1179 		}
1180         else if ( pObj->ISA(SwAnchoredDrawObject) )
1181         {
1182             if ( !static_cast<const SwAnchoredDrawObject*>(pObj)->IsValidPos() )
1183             {
1184                 return pObj;
1185             }
1186         }
1187 	}
1188 	return 0;
1189 }
1190 // <--
1191 
1192 sal_Bool SwLayAction::IsShortCut( SwPageFrm *&prPage )
1193 {
1194 	sal_Bool bRet = sal_False;
1195     const ViewShell *pSh = pRoot->GetCurrShell();
1196     const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1197 
1198 	//Wenn die Seite nicht Gueltig ist wird sie schnell formatiert, sonst
1199 	//gibts nix als Aerger.
1200 	if ( !prPage->IsValid() )
1201 	{
1202 		if ( bBrowse )
1203 		{
1204             /// OD 15.10.2002 #103517# - format complete page
1205             /// Thus, loop on all lowers of the page <prPage>, instead of only
1206             /// format its first lower.
1207             /// NOTE: In online layout (bBrowse == sal_True) a page can contain
1208             ///     a header frame and/or a footer frame beside the body frame.
1209 			prPage->Calc();
1210             SwFrm* pPageLowerFrm = prPage->Lower();
1211             while ( pPageLowerFrm )
1212             {
1213                 pPageLowerFrm->Calc();
1214                 pPageLowerFrm = pPageLowerFrm->GetNext();
1215             }
1216 		}
1217 		else
1218 			FormatLayout( prPage );
1219 		if ( IsAgain() )
1220 			return sal_False;
1221 	}
1222 
1223 
1224 	const SwRect &rVis = pImp->GetShell()->VisArea();
1225 	if ( (prPage->Frm().Top() >= rVis.Bottom()) ||
1226 		 (prPage->Frm().Left()>= rVis.Right()) )
1227 	{
1228 		bRet = sal_True;
1229 
1230 		//Jetzt wird es ein bischen unangenehm: Der erste CntntFrm dieser Seite
1231 		//im Bodytext muss Formatiert werden, wenn er dabei die Seite
1232 		//wechselt, muss ich nochmal eine Seite zuvor anfangen, denn
1233 		//es wurde ein PageBreak verarbeitet.
1234 //Noch unangenehmer: Der naechste CntntFrm ueberhaupt muss
1235 		//Formatiert werden, denn es kann passieren, dass kurzfristig
1236 		//leere Seiten existieren (Bsp. Absatz ueber mehrere Seiten
1237 		//wird geloescht oder verkleinert).
1238 
1239 		//Ist fuer den Browser uninteressant, wenn der letzte Cnt davor bereits
1240 		//nicht mehr sichbar ist.
1241 
1242 		const SwPageFrm *p2ndPage = prPage;
1243 		const SwCntntFrm *pCntnt;
1244 		const SwLayoutFrm* pBody = p2ndPage->FindBodyCont();
1245 		if( p2ndPage->IsFtnPage() && pBody )
1246 			pBody = (SwLayoutFrm*)pBody->GetNext();
1247 		pCntnt = pBody ? pBody->ContainsCntnt() : 0;
1248 		while ( p2ndPage && !pCntnt )
1249 		{
1250 			p2ndPage = (SwPageFrm*)p2ndPage->GetNext();
1251 			if( p2ndPage )
1252 			{
1253 				pBody = p2ndPage->FindBodyCont();
1254 				if( p2ndPage->IsFtnPage() && pBody )
1255 					pBody = (SwLayoutFrm*)pBody->GetNext();
1256 				pCntnt = pBody ? pBody->ContainsCntnt() : 0;
1257 			}
1258 		}
1259 		if ( pCntnt )
1260 		{
1261 			sal_Bool bTstCnt = sal_True;
1262 			if ( bBrowse )
1263 			{
1264 				//Der Cnt davor schon nicht mehr sichtbar?
1265 				const SwFrm *pLst = pCntnt;
1266 				if ( pLst->IsInTab() )
1267 					pLst = pCntnt->FindTabFrm();
1268 				if ( pLst->IsInSct() )
1269 					pLst = pCntnt->FindSctFrm();
1270 				pLst = pLst->FindPrev();
1271 				if ( pLst &&
1272 					 (pLst->Frm().Top() >= rVis.Bottom() ||
1273 					  pLst->Frm().Left()>= rVis.Right()) )
1274 				{
1275 					bTstCnt = sal_False;
1276 				}
1277 			}
1278 
1279 			if ( bTstCnt )
1280 			{
1281                 // --> OD 2004-06-04 #i27756# - check after each frame calculation,
1282                 // if the content frame has changed the page. If yes, no other
1283                 // frame calculation is performed
1284                 bool bPageChg = false;
1285 
1286                 if ( pCntnt->IsInSct() )
1287 				{
1288 					const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
1289 					if ( !pSct->IsValid() )
1290 					{
1291 						pSct->Calc();
1292 						pSct->SetCompletePaint();
1293 						if ( IsAgain() )
1294 							return sal_False;
1295                         // --> OD 2004-06-04 #i27756#
1296                         bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1297                                    prPage->GetPrev();
1298 					}
1299 				}
1300 
1301                 if ( !bPageChg && !pCntnt->IsValid() )
1302                 {
1303                     pCntnt->Calc();
1304 					pCntnt->SetCompletePaint();
1305 					if ( IsAgain() )
1306 						return sal_False;
1307                     // --> OD 2004-06-04 #i27756#
1308                     bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1309                                prPage->GetPrev();
1310 				}
1311 
1312                 if ( !bPageChg && pCntnt->IsInTab() )
1313 				{
1314 					const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm();
1315 					if ( !pTab->IsValid() )
1316 					{
1317 						pTab->Calc();
1318 						pTab->SetCompletePaint();
1319 						if ( IsAgain() )
1320 							return sal_False;
1321                         // --> OD 2004-06-04 #i27756#
1322                         bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1323                                    prPage->GetPrev();
1324 					}
1325 				}
1326 
1327                 if ( !bPageChg && pCntnt->IsInSct() )
1328 				{
1329 					const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
1330 					if ( !pSct->IsValid() )
1331 					{
1332 						pSct->Calc();
1333 						pSct->SetCompletePaint();
1334 						if ( IsAgain() )
1335 							return sal_False;
1336                         // --> OD 2004-06-04 #i27756#
1337                         bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1338                                    prPage->GetPrev();
1339 					}
1340 				}
1341 
1342                 // --> OD 2004-06-04 #i27756#
1343                 if ( bPageChg )
1344 				{
1345 					bRet = sal_False;
1346                     const SwPageFrm* pTmp = pCntnt->FindPageFrm();
1347                     if ( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() &&
1348                          pTmp->IsInvalid() )
1349                     {
1350 						prPage = (SwPageFrm*)pTmp;
1351                     }
1352 					else
1353                     {
1354 						prPage = (SwPageFrm*)prPage->GetPrev();
1355                     }
1356 				}
1357                 // --> OD 2005-04-25 #121980# - no shortcut, if at previous page
1358                 // an anchored object is registered, whose anchor is <pCntnt>.
1359                 else if ( prPage->GetPrev() &&
1360                           static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs() )
1361                 {
1362                     SwSortedObjs* pObjs =
1363                         static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs();
1364                     if ( pObjs )
1365                     {
1366                         sal_uInt32 i = 0;
1367                         for ( ; i < pObjs->Count(); ++i )
1368                         {
1369                             SwAnchoredObject* pObj = (*pObjs)[i];
1370                             if ( pObj->GetAnchorFrmContainingAnchPos() == pCntnt )
1371                             {
1372                                 bRet = sal_False;
1373                                 break;
1374                             }
1375                         }
1376                     }
1377                 }
1378                 // <--
1379 			}
1380 		}
1381 	}
1382 
1383 	if ( !bRet && bBrowse )
1384 	{
1385 		const long nBottom = rVis.Bottom();
1386         const SwAnchoredObject* pObj( 0L );
1387         if ( prPage->GetSortedObjs() &&
1388 			 (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) &&
1389              0 != (pObj = lcl_FindFirstInvaObj( prPage, nBottom )) &&
1390              pObj->GetObjRect().Top() <= nBottom )
1391 		{
1392 			return sal_False;
1393 		}
1394         const SwFrm* pFrm( 0L );
1395 		if ( prPage->IsInvalidLayout() &&
1396 			 0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) &&
1397 			 pFrm->Frm().Top() <= nBottom )
1398 		{
1399 			return sal_False;
1400 		}
1401 		if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) &&
1402 			 0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) &&
1403 			 pFrm->Frm().Top() <= nBottom )
1404 		{
1405 			return sal_False;
1406 		}
1407 		bRet = sal_True;
1408 	}
1409 	return bRet;
1410 }
1411 
1412 /*************************************************************************
1413 |*
1414 |*	SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab()
1415 |*
1416 |*	Ersterstellung		MA 30. Oct. 92
1417 |*	Letzte Aenderung	MA 18. May. 98
1418 |*
1419 |*************************************************************************/
1420 // OD 15.11.2002 #105155# - introduce support for vertical layout
1421 sal_Bool SwLayAction::FormatLayout( SwLayoutFrm *pLay, sal_Bool bAddRect )
1422 {
1423 	ASSERT( !IsAgain(), "Ungueltige Seite beachten." );
1424 	if ( IsAgain() )
1425 		return sal_False;
1426 
1427 	sal_Bool bChanged = sal_False;
1428 	sal_Bool bAlreadyPainted = sal_False;
1429     // OD 11.11.2002 #104414# - remember frame at complete paint
1430     SwRect aFrmAtCompletePaint;
1431 
1432 	if ( !pLay->IsValid() || pLay->IsCompletePaint() )
1433 	{
1434 		if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() )
1435 			pLay->GetPrev()->SetCompletePaint();
1436 
1437 		SwRect aOldRect( pLay->Frm() );
1438 		pLay->Calc();
1439 		if ( aOldRect != pLay->Frm() )
1440 			bChanged = sal_True;
1441 
1442 		sal_Bool bNoPaint = sal_False;
1443         if ( pLay->IsPageBodyFrm() &&
1444              pLay->Frm().Pos() == aOldRect.Pos() &&
1445              pLay->Lower() )
1446 		{
1447             const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
1448 			//Einschraenkungen wegen Kopf-/Fusszeilen
1449             if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
1450                 !( pLay->IsCompletePaint() && pLay->FindPageFrm()->FindFtnCont() ) )
1451 				bNoPaint = sal_True;
1452 		}
1453 
1454 		if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) )
1455 		{
1456 			SwRect aPaint( pLay->Frm() );
1457             // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for
1458             // page frames -> enlarge paint rectangle correspondingly.
1459             if ( pLay->IsPageFrm() )
1460             {
1461                 SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay);
1462                 const int nBorderWidth =
1463                         pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->BorderPxWidth(), 0 ) ).Width();
1464                 const int nShadowWidth =
1465                         pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->ShadowPxWidth(), 0 ) ).Width();
1466 
1467 				//mod #i6193# added sidebar width
1468                 const SwPostItMgr* pPostItMgr = pImp->GetShell()->GetPostItMgr();
1469 				const int nSidebarWidth = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
1470                 switch ( pPageFrm->SidebarPosition() )
1471                 {
1472                     case sw::sidebarwindows::SIDEBAR_LEFT:
1473                     {
1474                         aPaint.Left( aPaint.Left() - nBorderWidth - nSidebarWidth);
1475                         aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth);
1476                     }
1477                     break;
1478                     case sw::sidebarwindows::SIDEBAR_RIGHT:
1479                     {
1480                         aPaint.Left( aPaint.Left() - nBorderWidth );
1481                         aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth + nSidebarWidth);
1482                     }
1483                     break;
1484                     case sw::sidebarwindows::SIDEBAR_NONE:
1485                         // nothing to do
1486                     break;
1487                 }
1488 				aPaint.Top( aPaint.Top() - nBorderWidth );
1489 				aPaint.Bottom( aPaint.Bottom() + nBorderWidth + nShadowWidth);
1490             }
1491 
1492             sal_Bool bPageInBrowseMode = pLay->IsPageFrm();
1493             if( bPageInBrowseMode )
1494             {
1495                 const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
1496                 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() )
1497                     bPageInBrowseMode = sal_False;
1498             }
1499             if( bPageInBrowseMode )
1500 			{
1501                 // NOTE: no vertical layout in online layout
1502                 //Ist die Aenderung ueberhaupt sichtbar?
1503 				if ( pLay->IsCompletePaint() )
1504 				{
1505 					pImp->GetShell()->AddPaintRect( aPaint );
1506 					bAddRect = sal_False;
1507 				}
1508 				else
1509 				{
1510 					sal_uInt16 i;
1511 
1512 					SwRegionRects aRegion( aOldRect );
1513 					aRegion -= aPaint;
1514 					for ( i = 0; i < aRegion.Count(); ++i )
1515 						pImp->GetShell()->AddPaintRect( aRegion[i] );
1516                     aRegion.ChangeOrigin( aPaint );
1517 					aRegion.Remove( 0, aRegion.Count() );
1518 					aRegion.Insert( aPaint, 0 );
1519 					aRegion -= aOldRect;
1520 					for ( i = 0; i < aRegion.Count(); ++i )
1521 						pImp->GetShell()->AddPaintRect( aRegion[i] );
1522 				}
1523 
1524 			}
1525 			else
1526 			{
1527 				pImp->GetShell()->AddPaintRect( aPaint );
1528                 bAlreadyPainted = sal_True;
1529                 // OD 11.11.2002 #104414# - remember frame at complete paint
1530                 aFrmAtCompletePaint = pLay->Frm();
1531 			}
1532 
1533             // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing
1534             // between pages (not only for in online mode).
1535             if ( pLay->IsPageFrm() )
1536             {
1537                 const SwTwips nHalfDocBorder = GAPBETWEENPAGES;
1538                 const bool bLeftToRightViewLayout = pRoot->IsLeftToRightViewLayout();
1539                 const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext();
1540                 const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev();
1541 
1542                 if ( bPrev )
1543                 {
1544                     // top
1545                     SwRect aSpaceToPrevPage( pLay->Frm() );
1546                     const SwTwips nTop = aSpaceToPrevPage.Top() - nHalfDocBorder;
1547                     if ( nTop >= 0 )
1548                         aSpaceToPrevPage.Top( nTop );
1549                     aSpaceToPrevPage.Bottom( pLay->Frm().Top() );
1550                     pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
1551 
1552                     // left
1553                     aSpaceToPrevPage = pLay->Frm();
1554                     const SwTwips nLeft = aSpaceToPrevPage.Left() - nHalfDocBorder;
1555                     if ( nLeft >= 0 )
1556                         aSpaceToPrevPage.Left( nLeft );
1557                     aSpaceToPrevPage.Right( pLay->Frm().Left() );
1558                     pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
1559                 }
1560                 if ( bNext )
1561                 {
1562                     // bottom
1563                     SwRect aSpaceToNextPage( pLay->Frm() );
1564                     aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder );
1565                     aSpaceToNextPage.Top( pLay->Frm().Bottom() );
1566                     pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
1567 
1568                     // right
1569                     aSpaceToNextPage = pLay->Frm();
1570                     aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder );
1571                     aSpaceToNextPage.Left( pLay->Frm().Right() );
1572                     pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
1573                 }
1574             }
1575         }
1576 		pLay->ResetCompletePaint();
1577 	}
1578 
1579 	if ( IsPaint() && bAddRect &&
1580 		 !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() )
1581 	{
1582         // OD 15.11.2002 #105155# - vertical layout support
1583         SWRECTFN( pLay );
1584         SwRect aRect( pLay->GetUpper()->PaintArea() );
1585         (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() );
1586 		if ( !pImp->GetShell()->AddPaintRect( aRect ) )
1587 			pLay->ResetRetouche();
1588 	}
1589 
1590 	if( bAlreadyPainted )
1591 		bAddRect = sal_False;
1592 
1593 	CheckWaitCrsr();
1594 
1595 	if ( IsAgain() )
1596 		return sal_False;
1597 
1598 	//Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind
1599 
1600 	if ( pLay->IsFtnFrm() )	//Hat keine LayFrms als Lower.
1601 		return bChanged;
1602 
1603 	SwFrm *pLow = pLay->Lower();
1604 	sal_Bool bTabChanged = sal_False;
1605 	while ( pLow && pLow->GetUpper() == pLay )
1606 	{
1607 		if ( pLow->IsLayoutFrm() )
1608 		{
1609 			if ( pLow->IsTabFrm() )
1610 				bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
1611 			// bereits zum Loeschen angemeldete Ueberspringen
1612 			else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() )
1613 				bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
1614 		}
1615 		else if ( pImp->GetShell()->IsPaintLocked() )
1616 			//Abkuerzung im die Zyklen zu minimieren, bei Lock kommt das
1617 			//Paint sowieso (Primaer fuer Browse)
1618 			pLow->OptCalc();
1619 
1620 		if ( IsAgain() )
1621 			return sal_False;
1622 		pLow = pLow->GetNext();
1623 	}
1624     // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame
1625     // area has been already added and after formating its lowers the frame area
1626     // is enlarged.
1627     if ( bAlreadyPainted &&
1628          ( pLay->Frm().Width() > aFrmAtCompletePaint.Width() ||
1629            pLay->Frm().Height() > aFrmAtCompletePaint.Height() )
1630        )
1631     {
1632         pImp->GetShell()->AddPaintRect( pLay->Frm() );
1633     }
1634     return bChanged || bTabChanged;
1635 }
1636 
1637 sal_Bool SwLayAction::FormatLayoutFly( SwFlyFrm* pFly )
1638 {
1639 	ASSERT( !IsAgain(), "Ungueltige Seite beachten." );
1640 	if ( IsAgain() )
1641 		return sal_False;
1642 
1643     sal_Bool bChanged = false;
1644     sal_Bool bAddRect = true;
1645 
1646 	if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() )
1647 	{
1648 		//Der Frame hat sich veraendert, er wird jetzt Formatiert
1649 		const SwRect aOldRect( pFly->Frm() );
1650 		pFly->Calc();
1651 		bChanged = aOldRect != pFly->Frm();
1652 
1653         if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) &&
1654                     pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
1655             pImp->GetShell()->AddPaintRect( pFly->Frm() );
1656 
1657         if ( bChanged )
1658             pFly->Invalidate();
1659         else
1660             pFly->Validate();
1661 /*
1662         //mba: it's unclear why we should invalidate always, so I remove it
1663 		//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1664 	    if ( IsPaint() && bAddRect && pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
1665 			pImp->GetShell()->AddPaintRect( pFly->Frm() );
1666 
1667         pFly->Invalidate();
1668 */
1669         bAddRect = false;
1670 		pFly->ResetCompletePaint();
1671 	}
1672 
1673 	if ( IsAgain() )
1674 		return sal_False;
1675 
1676 	//Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind
1677     sal_Bool bTabChanged = false;
1678 	SwFrm *pLow = pFly->Lower();
1679 	while ( pLow )
1680 	{
1681 		if ( pLow->IsLayoutFrm() )
1682 		{
1683 			if ( pLow->IsTabFrm() )
1684 				bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
1685 			else
1686 				bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
1687 		}
1688 		pLow = pLow->GetNext();
1689 	}
1690 	return bChanged || bTabChanged;
1691 }
1692 
1693 // OD 31.10.2002 #104100#
1694 // Implement vertical layout support
1695 sal_Bool SwLayAction::FormatLayoutTab( SwTabFrm *pTab, sal_Bool bAddRect )
1696 {
1697 	ASSERT( !IsAgain(), "8-) Ungueltige Seite beachten." );
1698 	if ( IsAgain() || !pTab->Lower() )
1699 		return sal_False;
1700 
1701 	IDocumentTimerAccess *pTimerAccess = pRoot->GetFmt()->getIDocumentTimerAccess();
1702 	pTimerAccess->BlockIdling();
1703 
1704     sal_Bool bChanged = sal_False;
1705     sal_Bool bPainted = sal_False;
1706 
1707 	const SwPageFrm *pOldPage = pTab->FindPageFrm();
1708 
1709     // OD 31.10.2002 #104100# - vertical layout support
1710     // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and
1711     // <SwRectFn fnRect> for table frame <pTab>.
1712     SWRECTFN( pTab );
1713 
1714 	if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() )
1715 	{
1716 		if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() )
1717         {
1718 			pTab->GetPrev()->SetCompletePaint();
1719         }
1720 
1721         const SwRect aOldRect( pTab->Frm() );
1722 		pTab->SetLowersFormatted( sal_False );
1723 		pTab->Calc();
1724 		if ( aOldRect != pTab->Frm() )
1725         {
1726 			bChanged = sal_True;
1727         }
1728         const SwRect aPaintFrm = pTab->PaintArea();
1729 
1730 		if ( IsPaint() && bAddRect )
1731 		{
1732             // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()>
1733             if ( !pTab->IsCompletePaint() &&
1734                  pTab->IsComplete() &&
1735 				 ( pTab->Frm().SSize() != pTab->Prt().SSize() ||
1736                    // OD 31.10.2002 #104100# - vertical layout support
1737                    (pTab->*fnRect->fnGetLeftMargin)() ) &&
1738                  pTab->Frm().HasArea()
1739                )
1740 			{
1741                 // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles.
1742                 SwRect aMarginRect;
1743 
1744                 SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)();
1745                 if ( nLeftMargin > 0)
1746                 {
1747                     aMarginRect = pTab->Frm();
1748                     (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin );
1749                     pImp->GetShell()->AddPaintRect( aMarginRect );
1750                 }
1751 
1752                 if ( (pTab->*fnRect->fnGetRightMargin)() > 0)
1753                 {
1754                     aMarginRect = pTab->Frm();
1755                     (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() );
1756                     pImp->GetShell()->AddPaintRect( aMarginRect );
1757                 }
1758 
1759                 SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)();
1760                 if ( nTopMargin > 0)
1761                 {
1762                     aMarginRect = pTab->Frm();
1763                     (aMarginRect.*fnRect->fnSetHeight)( nTopMargin );
1764                     pImp->GetShell()->AddPaintRect( aMarginRect );
1765                 }
1766 
1767                 if ( (pTab->*fnRect->fnGetBottomMargin)() > 0)
1768                 {
1769                     aMarginRect = pTab->Frm();
1770                     (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
1771                     pImp->GetShell()->AddPaintRect( aMarginRect );
1772                 }
1773 			}
1774 			else if ( pTab->IsCompletePaint() )
1775 			{
1776 				pImp->GetShell()->AddPaintRect( aPaintFrm );
1777 				bAddRect = sal_False;
1778 				bPainted = sal_True;
1779 			}
1780 
1781             if ( pTab->IsRetouche() && !pTab->GetNext() )
1782 			{
1783 				SwRect aRect( pTab->GetUpper()->PaintArea() );
1784                 // OD 04.11.2002 #104100# - vertical layout support
1785                 (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
1786                 if ( !pImp->GetShell()->AddPaintRect( aRect ) )
1787 					pTab->ResetRetouche();
1788 			}
1789 		}
1790 		else
1791 			bAddRect = sal_False;
1792 
1793         if ( pTab->IsCompletePaint() && !pOptTab )
1794 			pOptTab = pTab;
1795 		pTab->ResetCompletePaint();
1796 	}
1797 	if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() )
1798 	{
1799         // OD 04.10.2002 #102779#
1800         // set correct rectangle for retouche: area between bottom of table frame
1801         // and bottom of paint area of the upper frame.
1802         SwRect aRect( pTab->GetUpper()->PaintArea() );
1803         // OD 04.11.2002 #104100# - vertical layout support
1804         (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
1805 		if ( !pImp->GetShell()->AddPaintRect( aRect ) )
1806 			pTab->ResetRetouche();
1807 	}
1808 
1809 	CheckWaitCrsr();
1810 
1811     pTimerAccess->UnblockIdling();
1812 
1813 	//Heftige Abkuerzung!
1814 	if ( pTab->IsLowersFormatted() &&
1815          (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) )
1816 		return sal_False;
1817 
1818 	//Jetzt noch die Lowers versorgen
1819 	if ( IsAgain() )
1820 		return sal_False;
1821 
1822     // OD 20.10.2003 #112464# - for savety reasons:
1823     // check page number before formatting lowers.
1824     if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) )
1825         SetNextCycle( sal_True );
1826 
1827     // OD 20.10.2003 #112464# - format lowers, only if table frame is valid
1828     if ( pTab->IsValid() )
1829     {
1830         SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower();
1831         while ( pLow )
1832         {
1833             bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
1834             if ( IsAgain() )
1835                 return sal_False;
1836             pLow = (SwLayoutFrm*)pLow->GetNext();
1837         }
1838     }
1839 
1840 	return bChanged;
1841 }
1842 
1843 /*************************************************************************
1844 |*
1845 |*	SwLayAction::FormatCntnt()
1846 |*
1847 |*	Ersterstellung		MA 30. Oct. 92
1848 |*	Letzte Aenderung	MA 16. Nov. 95
1849 |*
1850 |*************************************************************************/
1851 sal_Bool SwLayAction::FormatCntnt( const SwPageFrm *pPage )
1852 {
1853 	const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
1854     const ViewShell *pSh = pRoot->GetCurrShell();
1855     const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1856 
1857 	while ( pCntnt && pPage->IsAnLower( pCntnt ) )
1858 	{
1859 		//Wenn der Cntnt sich eh nicht veraendert koennen wir ein paar
1860 		//Abkuerzungen nutzen.
1861 		const sal_Bool bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() ||
1862 						   pCntnt->IsRetouche() || pCntnt->GetDrawObjs();
1863 		if ( bFull )
1864 		{
1865 			//Damit wir nacher nicht suchen muessen.
1866 			const sal_Bool bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow();
1867 			const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0;
1868 			const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0;
1869 
1870 			const SwLayoutFrm*pOldUpper  = pCntnt->GetUpper();
1871 			const SwTabFrm *pTab = pCntnt->FindTabFrm();
1872 			const sal_Bool bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint();
1873 			const sal_Bool bOldPaint = IsPaint();
1874 			bPaint = bOldPaint && !(pTab && pTab == pOptTab);
1875 			_FormatCntnt( pCntnt, pPage );
1876             // --> OD 2004-11-05 #i26945# - reset <bPaint> before format objects
1877             bPaint = bOldPaint;
1878             // <--
1879 
1880             // OD 2004-05-10 #i28701# - format floating screen object at content frame.
1881             // No format, if action flag <bAgain> is set or action is interrupted.
1882             // OD 2004-08-30 #117736# - allow format on interruption of action, if
1883             // it's the format for this interrupt
1884             // --> OD 2004-11-01 #i23129#, #i36347# - pass correct page frame
1885             // to the object formatter.
1886             if ( !IsAgain() &&
1887                  ( !IsInterrupt() || mbFormatCntntOnInterrupt ) &&
1888                  pCntnt->IsTxtFrm() &&
1889                  !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCntnt)),
1890                                                       *(pCntnt->FindPageFrm()), this ) )
1891             // <--
1892             {
1893                 return sal_False;
1894             }
1895 
1896 			if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
1897 			{
1898 				const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
1899 				((SwTxtFrm*)pCntnt)->RecalcAllLines();
1900 				if ( IsPaintExtraData() && IsPaint() &&
1901 					 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
1902 					pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
1903 			}
1904 
1905 			if ( IsAgain() )
1906 				return sal_False;
1907 
1908 			//Wenn Layout oder Flys wieder Invalid sind breche ich die Verarbeitung
1909 			//vorlaeufig ab - allerdings nicht fuer die BrowseView, denn dort wird
1910 			//das Layout staendig ungueltig, weil die Seitenhoehe angepasst wird.
1911 			//Desgleichen wenn der Benutzer weiterarbeiten will und mindestens ein
1912 			//Absatz verarbeitet wurde.
1913 			if ( (!pTab || (pTab && !bInValid)) )
1914 			{
1915                 CheckIdleEnd();
1916                 // OD 14.04.2003 #106346# - consider interrupt formatting.
1917                 if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) ||
1918                      ( !bBrowse && pPage->IsInvalidLayout() ) ||
1919                      // OD 07.05.2003 #109435# - consider interrupt formatting
1920                      ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt )
1921                    )
1922 					return sal_False;
1923 			}
1924 			if ( pOldUpper != pCntnt->GetUpper() )
1925 			{
1926 				const sal_uInt16 nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum();
1927 				if (  nCurNum < pPage->GetPhyPageNum() )
1928 					nPreInvaPage = nCurNum;
1929 
1930 				//Wenn der Frm mehr als eine Seite rueckwaerts geflossen ist, so
1931 				//fangen wir nocheinmal von vorn an damit wir nichts auslassen.
1932 				if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 )
1933 				{
1934 					SetNextCycle( sal_True );
1935                     // OD 07.05.2003 #109435# - consider interrupt formatting
1936                     if ( !mbFormatCntntOnInterrupt )
1937                     {
1938                         return sal_False;
1939                     }
1940 				}
1941 			}
1942 			//Wenn der Frame die Seite vorwaerts gewechselt hat, so lassen wir
1943 			//den Vorgaenger nocheinmal durchlaufen.
1944 			//So werden einerseits Vorgaenger erwischt, die jetzt f?r Retouche
1945 			//verantwortlich sind, andererseits werden die Fusszeilen
1946 			//auch angefasst.
1947 			sal_Bool bSetCntnt = sal_True;
1948 			if ( pCntntPrev )
1949 			{
1950                 if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) )
1951 					pPage->InvalidateCntnt();
1952 				if ( pOldUpper != pCntnt->GetUpper() &&
1953 					 pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() )
1954 				{
1955 					pCntnt = pCntntPrev;
1956 					bSetCntnt = sal_False;
1957 				}
1958 			}
1959 			if ( bSetCntnt )
1960 			{
1961 				if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1962 					 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
1963 				{
1964 					const long nBottom = pImp->GetShell()->VisArea().Bottom();
1965 					const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
1966 															nBottom, pCntnt );
1967 					if ( !pTmp )
1968 					{
1969 						if ( (!(IS_FLYS && IS_INVAFLY) ||
1970                               !lcl_FindFirstInvaObj( pPage, nBottom )) &&
1971 							  (!pPage->IsInvalidLayout() ||
1972 							   !lcl_FindFirstInvaLay( pPage, nBottom )))
1973 							SetBrowseActionStop( sal_True );
1974                         // OD 14.04.2003 #106346# - consider interrupt formatting.
1975                         if ( !mbFormatCntntOnInterrupt )
1976                         {
1977                             return sal_False;
1978                         }
1979 					}
1980 				}
1981 				pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm();
1982 			}
1983 
1984 			RESCHEDULE;
1985 		}
1986 		else
1987 		{
1988 			if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
1989 			{
1990 				const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
1991 				((SwTxtFrm*)pCntnt)->RecalcAllLines();
1992 				if ( IsPaintExtraData() && IsPaint() &&
1993 					 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
1994 					pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
1995 			}
1996 
1997 			//Falls der Frm schon vor der Abarbeitung hier formatiert wurde.
1998 			if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() &&
1999 				  IsPaint() )
2000 				PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom());
2001 			if ( IsIdle() )
2002 			{
2003 				CheckIdleEnd();
2004                 // OD 14.04.2003 #106346# - consider interrupt formatting.
2005                 if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
2006 					return sal_False;
2007 			}
2008 			if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
2009 				 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
2010 			{
2011 				const long nBottom = pImp->GetShell()->VisArea().Bottom();
2012 				const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
2013 													nBottom, pCntnt );
2014 				if ( !pTmp )
2015 				{
2016 					if ( (!(IS_FLYS && IS_INVAFLY) ||
2017                             !lcl_FindFirstInvaObj( pPage, nBottom )) &&
2018 							(!pPage->IsInvalidLayout() ||
2019 							!lcl_FindFirstInvaLay( pPage, nBottom )))
2020 						SetBrowseActionStop( sal_True );
2021                     // OD 14.04.2003 #106346# - consider interrupt formatting.
2022                     if ( !mbFormatCntntOnInterrupt )
2023                     {
2024                         return sal_False;
2025                     }
2026 				}
2027 			}
2028 			pCntnt = pCntnt->GetNextCntntFrm();
2029 		}
2030 	}
2031 	CheckWaitCrsr();
2032     // OD 14.04.2003 #106346# - consider interrupt formatting.
2033     return !IsInterrupt() || mbFormatCntntOnInterrupt;
2034 }
2035 /*************************************************************************
2036 |*
2037 |*	SwLayAction::_FormatCntnt()
2038 |*
2039 |* 	Beschreibung		Returnt sal_True wenn der Absatz verarbeitet wurde,
2040 |* 						sal_False wenn es nichts zu verarbeiten gab.
2041 |*	Ersterstellung		MA 07. Dec. 92
2042 |*	Letzte Aenderung	MA 11. Mar. 98
2043 |*
2044 |*************************************************************************/
2045 void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt,
2046                                 const SwPageFrm  *pPage )
2047 {
2048 	//wird sind hier evtl. nur angekommen, weil der Cntnt DrawObjekte haelt.
2049 	const sal_Bool bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() &&
2050 						 !pCntnt->IsRetouche();
2051     SWRECTFN( pCntnt )
2052 	if ( !bDrawObjsOnly && IsPaint() )
2053 	{
2054 		const SwRect aOldRect( pCntnt->UnionFrm() );
2055         const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)();
2056 		pCntnt->OptCalc();
2057 		if( IsAgain() )
2058 			return;
2059         if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(),
2060                                 (aOldRect.*fnRect->fnGetBottom)() ) < 0 )
2061         {
2062 			pCntnt->SetRetouche();
2063         }
2064         PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom);
2065 	}
2066 	else
2067 	{
2068 		if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() )
2069             PaintCntnt( pCntnt, pPage, pCntnt->Frm(),
2070                         (pCntnt->Frm().*fnRect->fnGetBottom)() );
2071 		pCntnt->OptCalc();
2072 	}
2073 }
2074 
2075 /*************************************************************************
2076 |*
2077 |*	SwLayAction::_FormatFlyCntnt()
2078 |*
2079 |*	Beschreibung:
2080 |* 		- Returnt sal_True wenn alle Cntnts des Flys vollstaendig verarbeitet
2081 |* 		  wurden. sal_False wenn vorzeitig unterbrochen wurde.
2082 |*	Ersterstellung		MA 02. Dec. 92
2083 |*	Letzte Aenderung	MA 24. Jun. 96
2084 |*
2085 |*************************************************************************/
2086 sal_Bool SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly )
2087 {
2088 	const SwCntntFrm *pCntnt = pFly->ContainsCntnt();
2089 
2090 	while ( pCntnt )
2091 	{
2092         // OD 2004-05-10 #i28701#
2093         _FormatCntnt( pCntnt, pCntnt->FindPageFrm() );
2094 
2095         // --> OD 2004-07-23 #i28701# - format floating screen objects
2096         // at content text frame
2097         // --> OD 2004-11-02 #i23129#, #i36347# - pass correct page frame
2098         // to the object formatter.
2099         if ( pCntnt->IsTxtFrm() &&
2100              !SwObjectFormatter::FormatObjsAtFrm(
2101                                             *(const_cast<SwCntntFrm*>(pCntnt)),
2102                                             *(pCntnt->FindPageFrm()), this ) )
2103         // <--
2104         {
2105             // restart format with first content
2106             pCntnt = pFly->ContainsCntnt();
2107             continue;
2108         }
2109         // <--
2110 
2111 		if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
2112 		{
2113 			const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
2114 			((SwTxtFrm*)pCntnt)->RecalcAllLines();
2115 			if ( IsPaintExtraData() && IsPaint() &&
2116 				 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
2117 				pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
2118 		}
2119 
2120 		if ( IsAgain() )
2121 			return sal_False;
2122 
2123 		//wenn eine Eingabe anliegt breche ich die Verarbeitung ab.
2124         if ( !pFly->IsFlyInCntFrm() )
2125 		{
2126 			CheckIdleEnd();
2127             // OD 14.04.2003 #106346# - consider interrupt formatting.
2128             if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
2129 				return sal_False;
2130 		}
2131 		pCntnt = pCntnt->GetNextCntntFrm();
2132 	}
2133 	CheckWaitCrsr();
2134     // OD 14.04.2003 #106346# - consider interrupt formatting.
2135     return !(IsInterrupt() && !mbFormatCntntOnInterrupt);
2136 }
2137 
2138 sal_Bool SwLayAction::IsStopPrt() const
2139 {
2140 	sal_Bool bResult = sal_False;
2141 
2142 	if (pImp != NULL && pProgress != NULL)
2143 		bResult = pImp->IsStopPrt();
2144 
2145 	return bResult;
2146 }
2147 
2148 /*************************************************************************
2149 |*
2150 |*	SwLayAction::FormatSpelling(), _FormatSpelling()
2151 |*
2152 |*	Ersterstellung		AMA 01. Feb. 96
2153 |*	Letzte Aenderung	AMA 01. Feb. 96
2154 |*
2155 |*************************************************************************/
2156 sal_Bool SwLayIdle::_DoIdleJob( const SwCntntFrm *pCnt, IdleJobType eJob )
2157 {
2158 	ASSERT( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" );
2159     // robust against misuse by e.g. #i52542#
2160     if( !pCnt->IsTxtFrm() )
2161         return sal_False;
2162 
2163     const SwTxtNode* pTxtNode = pCnt->GetNode()->GetTxtNode();
2164 
2165     bool bProcess = false;
2166     switch ( eJob )
2167     {
2168         case ONLINE_SPELLING :
2169             bProcess = pTxtNode->IsWrongDirty(); break;
2170         case AUTOCOMPLETE_WORDS :
2171             bProcess = pTxtNode->IsAutoCompleteWordDirty(); break;
2172         case WORD_COUNT :
2173             bProcess = pTxtNode->IsWordCountDirty(); break;
2174         case SMART_TAGS :   // SMARTTAGS
2175             bProcess = pTxtNode->IsSmartTagDirty(); break;
2176     }
2177 
2178     if( bProcess )
2179 	{
2180         ViewShell *pSh = pImp->GetShell();
2181         if( STRING_LEN == nTxtPos )
2182 		{
2183 			--nTxtPos;
2184             if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() )
2185 			{
2186 				SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr();
2187 				if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() )
2188 				{
2189 					pCntntNode = pCrsr->GetCntntNode();
2190 					nTxtPos =  pCrsr->GetPoint()->nContent.GetIndex();
2191 				}
2192 			}
2193 		}
2194 
2195         switch ( eJob )
2196         {
2197             case ONLINE_SPELLING :
2198             {
2199                 SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode,  *pSh->GetViewOptions(), nTxtPos ) );
2200                 bPageValid = bPageValid && !pTxtNode->IsWrongDirty();
2201                 if( !bPageValid )
2202                     bAllValid = sal_False;
2203                 if ( aRepaint.HasArea() )
2204                     pImp->GetShell()->InvalidateWindows( aRepaint );
2205                 if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) )
2206                     return sal_True;
2207                 break;
2208             }
2209             case AUTOCOMPLETE_WORDS :
2210                 ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos );
2211                 if ( Application::AnyInput( INPUT_ANY ) )
2212                     return sal_True;
2213                 break;
2214             case WORD_COUNT :
2215             {
2216                 const xub_StrLen nEnd = pTxtNode->GetTxt().Len();
2217                 SwDocStat aStat;
2218                 pTxtNode->CountWords( aStat, 0, nEnd );
2219                 if ( Application::AnyInput( INPUT_ANY ) )
2220                     return sal_True;
2221                 break;
2222             }
2223             case SMART_TAGS : // SMARTTAGS
2224             {
2225                 const SwRect aRepaint( ((SwTxtFrm*)pCnt)->SmartTagScan( pCntntNode, nTxtPos ) );
2226                 bPageValid = bPageValid && !pTxtNode->IsSmartTagDirty();
2227                 if( !bPageValid )
2228                     bAllValid = sal_False;
2229                 if ( aRepaint.HasArea() )
2230                     pImp->GetShell()->InvalidateWindows( aRepaint );
2231                 if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) )
2232                     return sal_True;
2233                 break;
2234             }
2235         }
2236     }
2237 
2238     //Die im Absatz verankerten Flys wollen auch mitspielen.
2239 	if ( pCnt->GetDrawObjs() )
2240 	{
2241         const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
2242 		for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2243 		{
2244             SwAnchoredObject* pObj = rObjs[i];
2245             if ( pObj->ISA(SwFlyFrm) )
2246 			{
2247                 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2248 				if ( pFly->IsFlyInCntFrm() )
2249 				{
2250 					const SwCntntFrm *pC = pFly->ContainsCntnt();
2251 					while( pC )
2252 					{
2253                         if ( pC->IsTxtFrm() )
2254                         {
2255                             if ( _DoIdleJob( pC, eJob ) )
2256                                 return sal_True;
2257                         }
2258 						pC = pC->GetNextCntntFrm();
2259 					}
2260 				}
2261 			}
2262 		}
2263 	}
2264 	return sal_False;
2265 }
2266 
2267 sal_Bool SwLayIdle::DoIdleJob( IdleJobType eJob, sal_Bool bVisAreaOnly )
2268 {
2269 	//Spellchecken aller Inhalte der Seiten. Entweder nur der sichtbaren
2270     //Seiten oder eben aller.
2271     const ViewShell* pViewShell = pImp->GetShell();
2272     const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
2273     const SwDoc* pDoc = pViewShell->GetDoc();
2274 
2275     switch ( eJob )
2276     {
2277         case ONLINE_SPELLING :
2278             if( !pViewOptions->IsOnlineSpell() )
2279                 return sal_False;
2280             break;
2281         case AUTOCOMPLETE_WORDS :
2282             if( !pViewOptions->IsAutoCompleteWords() ||
2283                  pDoc->GetAutoCompleteWords().IsLockWordLstLocked())
2284                 return sal_False;
2285             break;
2286         case WORD_COUNT :
2287             if ( !pViewShell->getIDocumentStatistics()->GetDocStat().bModified )
2288                 return sal_False;
2289             break;
2290         case SMART_TAGS :
2291             if ( pDoc->GetDocShell()->IsHelpDocument() ||
2292                  pDoc->isXForms() ||
2293                 !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
2294                 return sal_False;
2295             break;
2296         default: ASSERT( false, "Unknown idle job type" )
2297     }
2298 
2299     SwPageFrm *pPage;
2300 	if ( bVisAreaOnly )
2301 		pPage = pImp->GetFirstVisPage();
2302 	else
2303 		pPage = (SwPageFrm*)pRoot->Lower();
2304 
2305 	pCntntNode = NULL;
2306 	nTxtPos = STRING_LEN;
2307 
2308 	while ( pPage )
2309 	{
2310         bPageValid = sal_True;
2311 		const SwCntntFrm *pCnt = pPage->ContainsCntnt();
2312 		while( pCnt && pPage->IsAnLower( pCnt ) )
2313 		{
2314             if ( _DoIdleJob( pCnt, eJob ) )
2315 				return sal_True;
2316 			pCnt = pCnt->GetNextCntntFrm();
2317 		}
2318 		if ( pPage->GetSortedObjs() )
2319 		{
2320 			for ( sal_uInt16 i = 0; pPage->GetSortedObjs() &&
2321 								i < pPage->GetSortedObjs()->Count(); ++i )
2322 			{
2323                 const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
2324                 if ( pObj->ISA(SwFlyFrm) )
2325 				{
2326                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
2327 					const SwCntntFrm *pC = pFly->ContainsCntnt();
2328 					while( pC )
2329 					{
2330                         if ( pC->IsTxtFrm() )
2331                         {
2332                             if ( _DoIdleJob( pC, eJob ) )
2333                                 return sal_True;
2334                         }
2335 						pC = pC->GetNextCntntFrm();
2336 					}
2337 				}
2338 			}
2339 		}
2340 
2341 		if( bPageValid )
2342         {
2343             switch ( eJob )
2344             {
2345                 case ONLINE_SPELLING : pPage->ValidateSpelling(); break;
2346                 case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break;
2347                 case WORD_COUNT : pPage->ValidateWordCount(); break;
2348                 case SMART_TAGS : pPage->ValidateSmartTags(); break; // SMARTTAGS
2349             }
2350         }
2351 
2352 		pPage = (SwPageFrm*)pPage->GetNext();
2353 		if ( pPage && bVisAreaOnly &&
2354 			 !pPage->Frm().IsOver( pImp->GetShell()->VisArea()))
2355              break;
2356     }
2357 	return sal_False;
2358 }
2359 
2360 
2361 #ifdef DBG_UTIL
2362 #if OSL_DEBUG_LEVEL > 1
2363 
2364 /*************************************************************************
2365 |*
2366 |*	void SwLayIdle::SwLayIdle()
2367 |*
2368 |*	Ersterstellung		MA ??
2369 |*	Letzte Aenderung	MA 09. Jun. 94
2370 |*
2371 |*************************************************************************/
2372 void SwLayIdle::ShowIdle( ColorData eColorData )
2373 {
2374 	if ( !bIndicator )
2375 	{
2376 		bIndicator = sal_True;
2377 		Window *pWin = pImp->GetShell()->GetWin();
2378 		if ( pWin )
2379 		{
2380 			Rectangle aRect( 0, 0, 5, 5 );
2381 			aRect = pWin->PixelToLogic( aRect );
2382             // OD 2004-04-23 #116347#
2383             pWin->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
2384 			pWin->SetFillColor( eColorData );
2385 			pWin->SetLineColor();
2386 			pWin->DrawRect( aRect );
2387 			pWin->Pop();
2388 		}
2389 	}
2390 }
2391 #define SHOW_IDLE( ColorData ) ShowIdle( ColorData )
2392 #else
2393 #define SHOW_IDLE( ColorData )
2394 #endif
2395 #else
2396 #define SHOW_IDLE( ColorData )
2397 #endif
2398 
2399 /*************************************************************************
2400 |*
2401 |*	void SwLayIdle::SwLayIdle()
2402 |*
2403 |*	Ersterstellung		MA 30. Oct. 92
2404 |*	Letzte Aenderung	MA 23. May. 95
2405 |*
2406 |*************************************************************************/
2407 SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) :
2408 	pRoot( pRt ),
2409 	pImp( pI )
2410 #ifdef DBG_UTIL
2411 #if OSL_DEBUG_LEVEL > 1
2412 	, bIndicator( sal_False )
2413 #endif
2414 #endif
2415 {
2416 	pImp->pIdleAct = this;
2417 
2418 	SHOW_IDLE( COL_LIGHTRED );
2419 
2420 	pImp->GetShell()->EnableSmooth( sal_False );
2421 
2422 	//Zuerst den Sichtbaren Bereich Spellchecken, nur wenn dort nichts
2423 	//zu tun war wird das IdleFormat angestossen.
2424     if ( !DoIdleJob( SMART_TAGS, sal_True ) &&
2425          !DoIdleJob( ONLINE_SPELLING, sal_True ) &&
2426          !DoIdleJob( AUTOCOMPLETE_WORDS, sal_True ) ) // SMARTTAGS
2427     {
2428 		//Formatieren und ggf. Repaint-Rechtecke an der ViewShell vormerken.
2429 		//Dabei muessen kuenstliche Actions laufen, damit es z.B. bei
2430 		//Veraenderungen der Seitenzahl nicht zu unerwuenschten Effekten kommt.
2431 		//Wir merken uns bei welchen Shells der Cursor sichtbar ist, damit
2432 		//wir ihn bei Dokumentaenderung ggf. wieder sichbar machen koennen.
2433 		SvBools aBools;
2434 		ViewShell *pSh = pImp->GetShell();
2435 		do
2436 		{	++pSh->nStartAction;
2437 			sal_Bool bVis = sal_False;
2438 			if ( pSh->ISA(SwCrsrShell) )
2439 			{
2440 #ifdef SW_CRSR_TIMER
2441 				((SwCrsrShell*)pSh)->ChgCrsrTimerFlag( sal_False );
2442 #endif
2443 				bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea());
2444 			}
2445 			aBools.push_back( bVis );
2446 			pSh = (ViewShell*)pSh->GetNext();
2447 		} while ( pSh != pImp->GetShell() );
2448 
2449 		SwLayAction aAction( pRoot, pImp );
2450 		aAction.SetInputType( INPUT_ANY );
2451 		aAction.SetIdle( sal_True );
2452 		aAction.SetWaitAllowed( sal_False );
2453 		aAction.Action();
2454 
2455 		//Weitere Start-/EndActions nur auf wenn irgendwo Paints aufgelaufen
2456 		//sind oder wenn sich die Sichtbarkeit des CharRects veraendert hat.
2457 		sal_Bool bActions = sal_False;
2458 		sal_uInt16 nBoolIdx = 0;
2459 		do
2460         {
2461             --pSh->nStartAction;
2462 
2463             if ( pSh->Imp()->GetRegion() )
2464 				bActions = sal_True;
2465 			else
2466 			{
2467 				SwRect aTmp( pSh->VisArea() );
2468 				pSh->UISizeNotify();
2469 
2470                 // --> FME 2006-08-03 #137134#
2471                 // Are we supposed to crash if pSh isn't a cursor shell?!
2472                 // bActions |= aTmp != pSh->VisArea() ||
2473                 //             aBools[nBoolIdx] != ((SwCrsrShell*)pSh)->GetCharRect().IsOver( pSh->VisArea() );
2474 
2475                 // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!)
2476                 // and the cursor is visible.
2477                 bActions |= aTmp != pSh->VisArea();
2478                 if ( aTmp == pSh->VisArea() && pSh->ISA(SwCrsrShell) )
2479                 {
2480                     bActions |= aBools[nBoolIdx] !=
2481                                 static_cast<SwCrsrShell*>(pSh)->GetCharRect().IsOver( pSh->VisArea() );
2482                 }
2483             }
2484 
2485 			pSh = (ViewShell*)pSh->GetNext();
2486 			++nBoolIdx;
2487 		} while ( pSh != pImp->GetShell() );
2488 
2489 		if ( bActions )
2490 		{
2491 			//Start- EndActions aufsetzen. ueber die CrsrShell, damit der
2492 			//Cursor/Selektion und die VisArea korrekt gesetzt werden.
2493 			nBoolIdx = 0;
2494 			do
2495             {
2496                 sal_Bool bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) );
2497 
2498 				if ( bCrsrShell )
2499 					((SwCrsrShell*)pSh)->SttCrsrMove();
2500 //				else
2501 //					pSh->StartAction();
2502 
2503 				//Wenn Paints aufgelaufen sind, ist es am sinnvollsten schlicht das
2504 				//gesamte Window zu invalidieren. Anderfalls gibt es Paintprobleme
2505 				//deren Loesung unverhaeltnissmaessig aufwendig waere.
2506 				//fix(18176):
2507                 SwViewImp *pViewImp = pSh->Imp();
2508 				sal_Bool bUnlock = sal_False;
2509                 if ( pViewImp->GetRegion() )
2510 				{
2511                     pViewImp->DelRegion();
2512 
2513 					//Fuer Repaint mit virtuellem Device sorgen.
2514 					pSh->LockPaint();
2515 					bUnlock = sal_True;
2516 				}
2517 
2518 				if ( bCrsrShell )
2519 					//Wenn der Crsr sichbar war wieder sichbar machen, sonst
2520 					//EndCrsrMove mit sal_True fuer IdleEnd.
2521 					((SwCrsrShell*)pSh)->EndCrsrMove( sal_True^aBools[nBoolIdx] );
2522 //				else
2523 //					pSh->EndAction();
2524 				if( bUnlock )
2525 				{
2526 					if( bCrsrShell )
2527 					{
2528 						// UnlockPaint overwrite the selection from the
2529 						// CrsrShell and calls the virtual method paint
2530 						// to fill the virtual device. This fill dont have
2531 						// paint the selection! -> Set the focus flag at
2532 						// CrsrShell and it dont paint the selection.
2533 						((SwCrsrShell*)pSh)->ShLooseFcs();
2534 						pSh->UnlockPaint( sal_True );
2535 						((SwCrsrShell*)pSh)->ShGetFcs( sal_False );
2536 					}
2537 					else
2538 						pSh->UnlockPaint( sal_True );
2539 				}
2540 
2541 				pSh = (ViewShell*)pSh->GetNext();
2542 				++nBoolIdx;
2543 
2544 			} while ( pSh != pImp->GetShell() );
2545 		}
2546 
2547 		if ( !aAction.IsInterrupt() )
2548         {
2549             if ( !DoIdleJob( WORD_COUNT, sal_False ) )
2550                 if ( !DoIdleJob( SMART_TAGS, sal_False ) )
2551                     if ( !DoIdleJob( ONLINE_SPELLING, sal_False ) )
2552                         DoIdleJob( AUTOCOMPLETE_WORDS, sal_False ); // SMARTTAGS
2553         }
2554 
2555         bool bInValid = false;
2556 		const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions();
2557         const ViewShell* pViewShell = pImp->GetShell();
2558         // See conditions in DoIdleJob()
2559         const sal_Bool bSpell     = rVOpt.IsOnlineSpell();
2560         const sal_Bool bACmplWrd  = rVOpt.IsAutoCompleteWords();
2561         const sal_Bool bWordCount = pViewShell->getIDocumentStatistics()->GetDocStat().bModified;
2562         const sal_Bool bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() &&
2563                                 !pViewShell->GetDoc()->isXForms() &&
2564                                 SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
2565 
2566 		SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
2567 		do
2568         {
2569             bInValid = pPg->IsInvalidCntnt()    || pPg->IsInvalidLayout() ||
2570 					   pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() ||
2571 					   pPg->IsInvalidFlyInCnt() ||
2572 					   (bSpell && pPg->IsInvalidSpelling()) ||
2573                        (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) ||
2574                        (bWordCount && pPg->IsInvalidWordCount()) ||
2575                        (bSmartTags && pPg->IsInvalidSmartTags()); // SMARTTAGS
2576 
2577 			pPg = (SwPageFrm*)pPg->GetNext();
2578 
2579         } while ( pPg && !bInValid );
2580 
2581         if ( !bInValid )
2582 		{
2583 			pRoot->ResetIdleFormat();
2584 			SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell();
2585             pDocShell->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) );
2586 		}
2587 	}
2588 
2589 	pImp->GetShell()->EnableSmooth( sal_True );
2590 
2591     if( pImp->IsAccessible() )
2592         pImp->FireAccessibleEvents();
2593 
2594 #ifdef DBG_UTIL
2595 #if OSL_DEBUG_LEVEL > 1
2596 	if ( bIndicator && pImp->GetShell()->GetWin() )
2597 	{
2598 		// #i75172# Do not invalidate indicator, this may cause a endless loop. Instead, just repaint it
2599 		// This should be replaced by an overlay object in the future, anyways. Since it's only for debug
2600 		// purposes, it is not urgent.
2601 		static bool bCheckWithoutInvalidating(true);
2602 		if(bCheckWithoutInvalidating)
2603 		{
2604 			bIndicator = false; SHOW_IDLE( COL_LIGHTGREEN );
2605 		}
2606 		else
2607 		{
2608 			Rectangle aRect( 0, 0, 5, 5 );
2609 			aRect = pImp->GetShell()->GetWin()->PixelToLogic( aRect );
2610 			pImp->GetShell()->GetWin()->Invalidate( aRect );
2611 		}
2612 	}
2613 #endif
2614 #endif
2615 }
2616 
2617 SwLayIdle::~SwLayIdle()
2618 {
2619 	pImp->pIdleAct = 0;
2620 }
2621 
2622