Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <time.h>
22 : #include "rootfrm.hxx"
23 : #include "pagefrm.hxx"
24 : #include "cntfrm.hxx"
25 : #include "doc.hxx"
26 : #include "IDocumentDrawModelAccess.hxx"
27 : #include "IDocumentSettingAccess.hxx"
28 : #include "IDocumentLayoutAccess.hxx"
29 : #include "IDocumentStatistics.hxx"
30 : #include "IDocumentTimerAccess.hxx"
31 : #include "viewimp.hxx"
32 : #include "crsrsh.hxx"
33 : #include "dflyobj.hxx"
34 : #include "flyfrm.hxx"
35 : #include "frmtool.hxx"
36 : #include "dcontact.hxx"
37 : #include "ndtxt.hxx" // OnlineSpelling
38 : #include "frmfmt.hxx"
39 : #include "swregion.hxx"
40 : #include "viewopt.hxx" // test OnlineSpelling using internal TabPage
41 : #include "pam.hxx" // OnlineSpelling needed because of the current cursor position
42 : #include "dbg_lay.hxx"
43 : #include "layouter.hxx" // LoopControlling
44 : #include "docstat.hxx"
45 : #include "swevent.hxx"
46 :
47 : #include <sfx2/event.hxx>
48 :
49 : #include <ftnidx.hxx>
50 : #include <vcl/window.hxx>
51 : #include <vcl/svapp.hxx>
52 : #include <editeng/opaqitem.hxx>
53 : #include <editeng/brushitem.hxx>
54 : #include <SwSmartTagMgr.hxx>
55 :
56 : #define _LAYACT_CXX
57 : #include "layact.hxx"
58 : #include <swwait.hxx>
59 : #include <fmtsrnd.hxx>
60 : #include <fmtanchr.hxx>
61 : #include <tools/shl.hxx>
62 : #include <sfx2/progress.hxx>
63 : #include <docsh.hxx>
64 :
65 : #include "swmodule.hxx"
66 : #include "fmtline.hxx"
67 : #include "tabfrm.hxx"
68 : #include "ftnfrm.hxx"
69 : #include "txtfrm.hxx"
70 : #include "notxtfrm.hxx"
71 : #include "flyfrms.hxx"
72 : #include "mdiexp.hxx"
73 : #include "fmtornt.hxx"
74 : #include "sectfrm.hxx"
75 : #include "lineinfo.hxx"
76 : #include <acmplwrd.hxx>
77 : // #i28701#
78 : #include <sortedobjs.hxx>
79 : #include <objectformatter.hxx>
80 : #include <PostItMgr.hxx>
81 : #include <vector>
82 :
83 : /*************************************************************************
84 : |*
85 : |* SwLayAction static stuff
86 : |*
87 : |*************************************************************************/
88 :
89 : #define IS_FLYS (pPage->GetSortedObjs())
90 : #define IS_INVAFLY (pPage->IsInvalidFly())
91 :
92 :
93 : // Save some typing work to avoid accessing destroyed pages.
94 : #if OSL_DEBUG_LEVEL > 1
95 :
96 : static void BreakPoint()
97 : {
98 : return;
99 : }
100 :
101 : #define XCHECKPAGE \
102 : { if ( IsAgain() ) \
103 : { BreakPoint(); \
104 : if( bNoLoop ) \
105 : pLayoutAccess->GetLayouter()->EndLoopControl(); \
106 : return; \
107 : } \
108 : }
109 : #else
110 : #define XCHECKPAGE \
111 : { if ( IsAgain() ) \
112 : { \
113 : if( bNoLoop ) \
114 : pLayoutAccess->GetLayouter()->EndLoopControl(); \
115 : return; \
116 : } \
117 : }
118 : #endif
119 :
120 : #define RESCHEDULE \
121 : { \
122 : if ( IsReschedule() ) \
123 : { \
124 : if (pProgress) pProgress->Reschedule(); \
125 : ::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \
126 : } \
127 : }
128 :
129 25854 : inline sal_uLong Ticks()
130 : {
131 25854 : return 1000 * clock() / CLOCKS_PER_SEC;
132 : }
133 :
134 13356 : void SwLayAction::CheckWaitCrsr()
135 : {
136 13356 : RESCHEDULE
137 19623 : if ( !IsWait() && IsWaitAllowed() && IsPaint() &&
138 6267 : ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC/2) )
139 : {
140 2 : pWait = new SwWait( *pRoot->GetFmt()->GetDoc()->GetDocShell(), sal_True );
141 : }
142 13356 : }
143 :
144 : /*************************************************************************
145 : |*
146 : |* SwLayAction::CheckIdleEnd()
147 : |*
148 : |*************************************************************************/
149 : // Time over already?
150 8340 : inline void SwLayAction::CheckIdleEnd()
151 : {
152 8340 : if ( !IsInput() )
153 8222 : bInput = GetInputType() && Application::AnyInput( GetInputType() );
154 8340 : }
155 :
156 : /*************************************************************************
157 : |*
158 : |* SwLayAction::SetStatBar()
159 : |*
160 : |*************************************************************************/
161 500 : void SwLayAction::SetStatBar( sal_Bool bNew )
162 : {
163 500 : if ( bNew )
164 : {
165 500 : nEndPage = pRoot->GetPageNum();
166 500 : nEndPage += nEndPage * 10 / 100;
167 : }
168 : else
169 0 : nEndPage = USHRT_MAX;
170 500 : }
171 :
172 : /*************************************************************************
173 : |*
174 : |* SwLayAction::PaintCntnt()
175 : |*
176 : |* Description Depending of the type, the Cntnt is output
177 : |* according to it's changes, or the area to be outputted is
178 : |* registered with the region, respectively.
179 : |* PaintCntnt: fills the region
180 : |*
181 : |*************************************************************************/
182 876 : sal_Bool SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt,
183 : const SwPageFrm *pPage )
184 : {
185 876 : SwRegionRects aTmp( rRect );
186 876 : const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
187 876 : const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm();
188 : sal_uInt16 i;
189 :
190 2219 : for ( i = 0; i < rObjs.Count() && !aTmp.empty(); ++i )
191 : {
192 1343 : SdrObject *pO = rObjs[i]->DrawObj();
193 1343 : if ( !pO->ISA(SwVirtFlyDrawObj) )
194 104 : continue;
195 :
196 : // OD 2004-01-15 #110582# - do not consider invisible objects
197 1239 : const IDocumentDrawModelAccess* pIDDMA = pPage->GetFmt()->getIDocumentDrawModelAccess();
198 1239 : if ( !pIDDMA->IsVisibleLayerId( pO->GetLayer() ) )
199 : {
200 0 : continue;
201 : }
202 :
203 1239 : SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
204 :
205 1239 : if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) )
206 905 : continue;
207 :
208 334 : if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
209 0 : continue;
210 :
211 334 : if ( pFly->GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() )
212 0 : continue;
213 :
214 334 : if ( pSelfFly )
215 : {
216 125 : const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
217 125 : if ( pO->GetLayer() == pTmp->GetLayer() )
218 : {
219 125 : if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
220 : // Only look at things above us, if inside the same layer
221 108 : continue;
222 : }
223 : else
224 : {
225 0 : const sal_Bool bLowerOfSelf = pFly->IsLowerOf( pSelfFly );
226 0 : if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
227 : // Things from other layers are only interesting to us if
228 : // they're not transparent or lie inwards
229 0 : continue;
230 : }
231 : }
232 :
233 : /// OD 19.08.2002 #99657#
234 : /// Fly frame without a lower have to be subtracted from paint region.
235 : /// For checking, if fly frame contains transparent graphic or
236 : /// has surrounded contour, assure that fly frame has a lower
237 678 : if ( pFly->Lower() &&
238 462 : pFly->Lower()->IsNoTxtFrm() &&
239 118 : ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
240 0 : pFly->GetFmt()->GetSurround().IsContour() )
241 : )
242 : {
243 118 : continue;
244 : }
245 :
246 : /// OD 19.08.2002 #99657#
247 : /// Region of a fly frame with transparent background or a transparent
248 : /// shadow have not to be subtracted from paint region
249 216 : if ( pFly->IsBackgroundTransparent() ||
250 108 : pFly->IsShadowTransparent() )
251 : {
252 0 : continue;
253 : }
254 :
255 108 : aTmp -= pFly->Frm();
256 : }
257 :
258 876 : sal_Bool bRetPaint = sal_False;
259 1899 : for ( SwRects::const_iterator it = aTmp.begin(); it != aTmp.end(); ++it )
260 1023 : bRetPaint |= pImp->GetShell()->AddPaintRect( *it );
261 876 : return bRetPaint;
262 : }
263 :
264 10668 : inline sal_Bool SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt,
265 : const SwPageFrm *pPage,
266 : const SwRect &rRect )
267 : {
268 10668 : if ( rRect.HasArea() )
269 : {
270 10214 : if ( pPage->GetSortedObjs() )
271 876 : return PaintWithoutFlys( rRect, pCntnt, pPage );
272 : else
273 9338 : return pImp->GetShell()->AddPaintRect( rRect );
274 : }
275 454 : return sal_False;
276 : }
277 :
278 8788 : void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt,
279 : const SwPageFrm *pPage,
280 : const SwRect &rOldRect,
281 : long nOldBottom )
282 : {
283 8788 : SWRECTFN( pCnt )
284 :
285 8788 : if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() )
286 : {
287 3250 : SwRect aPaint( pCnt->PaintArea() );
288 3250 : if ( !_PaintCntnt( pCnt, pPage, aPaint ) )
289 690 : pCnt->ResetCompletePaint();
290 : }
291 : else
292 : {
293 : // paint the area between printing bottom and frame bottom and
294 : // the area left and right beside the frame, if its height changed.
295 5538 : long nOldHeight = (rOldRect.*fnRect->fnGetHeight)();
296 5538 : long nNewHeight = (pCnt->Frm().*fnRect->fnGetHeight)();
297 5538 : const bool bHeightDiff = nOldHeight != nNewHeight;
298 5538 : if( bHeightDiff )
299 : {
300 : // OD 05.11.2002 #94454# - consider whole potential paint area.
301 : //SwRect aDrawRect( pCnt->UnionFrm( sal_True ) );
302 736 : SwRect aDrawRect( pCnt->PaintArea() );
303 736 : if( nOldHeight > nNewHeight )
304 61 : nOldBottom = (pCnt->*fnRect->fnGetPrtBottom)();
305 736 : (aDrawRect.*fnRect->fnSetTop)( nOldBottom );
306 736 : _PaintCntnt( pCnt, pPage, aDrawRect );
307 : }
308 : // paint content area
309 5538 : SwRect aPaintRect = static_cast<SwTxtFrm*>(const_cast<SwCntntFrm*>(pCnt))->Paint();
310 5538 : _PaintCntnt( pCnt, pPage, aPaintRect );
311 : }
312 :
313 8788 : if ( pCnt->IsRetouche() && !pCnt->GetNext() )
314 : {
315 1144 : const SwFrm *pTmp = pCnt;
316 1144 : if( pCnt->IsInSct() )
317 : {
318 59 : const SwSectionFrm* pSct = pCnt->FindSctFrm();
319 59 : if( pSct->IsRetouche() && !pSct->GetNext() )
320 1 : pTmp = pSct;
321 : }
322 1144 : SwRect aRect( pTmp->GetUpper()->PaintArea() );
323 1144 : (aRect.*fnRect->fnSetTop)( (pTmp->*fnRect->fnGetPrtBottom)() );
324 1144 : if ( !_PaintCntnt( pCnt, pPage, aRect ) )
325 254 : pCnt->ResetRetouche();
326 : }
327 8788 : }
328 :
329 : /*************************************************************************
330 : |*
331 : |* SwLayAction::SwLayAction()
332 : |*
333 : |*************************************************************************/
334 19585 : SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) :
335 : pRoot( pRt ),
336 : pImp( pI ),
337 : pOptTab( 0 ),
338 : pWait( 0 ),
339 : pProgress(NULL),
340 : nPreInvaPage( USHRT_MAX ),
341 19585 : nStartTicks( Ticks() ),
342 : nInputType( 0 ),
343 : nEndPage( USHRT_MAX ),
344 39170 : nCheckPageNum( USHRT_MAX )
345 : {
346 19585 : bPaintExtraData = ::IsExtraData( pImp->GetShell()->GetDoc() );
347 19585 : bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True;
348 : bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
349 19585 : bUpdateExpFlds = bBrowseActionStop = bActionInProgress = sal_False;
350 : // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>.
351 19585 : mbFormatCntntOnInterrupt = sal_False;
352 :
353 19585 : pImp->pLayAct = this; // register there
354 19585 : }
355 :
356 19585 : SwLayAction::~SwLayAction()
357 : {
358 : OSL_ENSURE( !pWait, "Wait object not destroyed" );
359 19585 : pImp->pLayAct = 0; // unregister
360 19585 : }
361 :
362 : /*************************************************************************
363 : |*
364 : |* SwLayAction::Reset()
365 : |*
366 : |*************************************************************************/
367 2 : void SwLayAction::Reset()
368 : {
369 2 : pOptTab = 0;
370 2 : nStartTicks = Ticks();
371 2 : nInputType = 0;
372 2 : nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX;
373 2 : bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True;
374 : bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
375 2 : bUpdateExpFlds = bBrowseActionStop = sal_False;
376 2 : }
377 :
378 : /*************************************************************************
379 : |*
380 : |* SwLayAction::RemoveEmptyBrowserPages()
381 : |*
382 : |*************************************************************************/
383 :
384 16146 : sal_Bool SwLayAction::RemoveEmptyBrowserPages()
385 : {
386 : // switching from the normal to the browser mode, empty pages may be
387 : // retained for an annoyingly long time, so delete them here
388 16146 : sal_Bool bRet = sal_False;
389 16146 : const ViewShell *pSh = pRoot->GetCurrShell();
390 16146 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
391 : {
392 331 : SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
393 331 : do
394 : {
395 662 : if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) ||
396 331 : pPage->ContainsCntnt() )
397 331 : pPage = (SwPageFrm*)pPage->GetNext();
398 : else
399 : {
400 0 : bRet = sal_True;
401 0 : SwPageFrm *pDel = pPage;
402 0 : pPage = (SwPageFrm*)pPage->GetNext();
403 0 : pDel->Cut();
404 0 : delete pDel;
405 : }
406 : } while ( pPage );
407 : }
408 16146 : return bRet;
409 : }
410 :
411 :
412 : /*************************************************************************
413 : |*
414 : |* SwLayAction::Action()
415 : |*
416 : |*************************************************************************/
417 19587 : void SwLayAction::Action()
418 : {
419 19587 : bActionInProgress = sal_True;
420 :
421 : //TurboMode? Hands-off during idle-format
422 19587 : if ( IsPaint() && !IsIdle() && TurboAction() )
423 : {
424 3441 : delete pWait, pWait = 0;
425 3441 : pRoot->ResetTurboFlag();
426 3441 : bActionInProgress = sal_False;
427 3441 : pRoot->DeleteEmptySct();
428 23028 : return;
429 : }
430 16146 : else if ( pRoot->GetTurbo() )
431 : {
432 2 : pRoot->DisallowTurbo();
433 2 : const SwFrm *pFrm = pRoot->GetTurbo();
434 2 : pRoot->ResetTurbo();
435 2 : pFrm->InvalidatePage();
436 : }
437 16146 : pRoot->DisallowTurbo();
438 :
439 16146 : if ( IsCalcLayout() )
440 498 : SetCheckPages( sal_False );
441 :
442 16146 : InternalAction();
443 16146 : bAgain |= RemoveEmptyBrowserPages();
444 32292 : while ( IsAgain() )
445 : {
446 0 : bAgain = bNextCycle = sal_False;
447 0 : InternalAction();
448 0 : bAgain |= RemoveEmptyBrowserPages();
449 : }
450 16146 : pRoot->DeleteEmptySct();
451 :
452 16146 : delete pWait, pWait = 0;
453 :
454 : //Turbo-Action permitted again for all cases.
455 16146 : pRoot->ResetTurboFlag();
456 16146 : pRoot->ResetTurbo();
457 :
458 16146 : SetCheckPages( sal_True );
459 :
460 16146 : bActionInProgress = sal_False;
461 : }
462 :
463 14618 : SwPageFrm* SwLayAction::CheckFirstVisPage( SwPageFrm *pPage )
464 : {
465 14618 : SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt();
466 14618 : SwCntntFrm *pChk = pCnt;
467 14618 : sal_Bool bPageChgd = sal_False;
468 36298 : while ( pCnt && pCnt->IsFollow() )
469 7062 : pCnt = static_cast<SwCntntFrm*>(pCnt)->FindMaster();
470 14618 : if ( pCnt && pChk != pCnt )
471 4420 : { bPageChgd = sal_True;
472 4420 : pPage = pCnt->FindPageFrm();
473 : }
474 :
475 14618 : if ( !pPage->GetFmt()->GetDoc()->GetFtnIdxs().empty() )
476 : {
477 218 : SwFtnContFrm *pCont = pPage->FindFtnCont();
478 218 : if ( pCont )
479 : {
480 141 : pCnt = pCont->ContainsCntnt();
481 141 : pChk = pCnt;
482 282 : while ( pCnt && pCnt->IsFollow() )
483 0 : pCnt = (SwCntntFrm*)pCnt->FindPrev();
484 141 : if ( pCnt && pCnt != pChk )
485 : {
486 0 : if ( bPageChgd )
487 : {
488 : // Use the 'topmost' page
489 0 : SwPageFrm *pTmp = pCnt->FindPageFrm();
490 0 : if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() )
491 0 : pPage = pTmp;
492 : }
493 : else
494 0 : pPage = pCnt->FindPageFrm();
495 : }
496 : }
497 : }
498 14618 : return pPage;
499 : }
500 :
501 : // #114798# - unlock position on start and end of page
502 : // layout process.
503 4164 : static void unlockPositionOfObjects( SwPageFrm *pPageFrm )
504 : {
505 : assert( pPageFrm );
506 :
507 4164 : SwSortedObjs* pObjs = pPageFrm->GetSortedObjs();
508 4164 : if ( pObjs )
509 : {
510 382 : sal_uInt32 i = 0;
511 972 : for ( ; i < pObjs->Count(); ++i )
512 : {
513 590 : SwAnchoredObject* pObj = (*pObjs)[i];
514 590 : pObj->UnlockPosition();
515 : }
516 : }
517 4164 : }
518 :
519 16146 : void SwLayAction::InternalAction()
520 : {
521 : OSL_ENSURE( pRoot->Lower()->IsPageFrm(), ":-( No page below the root.");
522 :
523 16146 : pRoot->Calc();
524 :
525 : // Figure out the first invalid page or the first one to be formatted,
526 : // respectively. A complete-action means the first invalid page.
527 : // However, the first page to be formatted might be the one having the
528 : // number 1. If we're doing a fake formatting, the number of the first
529 : // page is the number of the first visible page.
530 17674 : SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() :
531 17674 : pImp->GetFirstVisPage();
532 16146 : if ( !pPage )
533 0 : pPage = (SwPageFrm*)pRoot->Lower();
534 :
535 : // If there's a first-flow-Cntnt in the first visible page that's also a Follow,
536 : // we switch the page back to the original master of that Cntnt.
537 16146 : if ( !IsComplete() )
538 14618 : pPage = CheckFirstVisPage( pPage );
539 16146 : sal_uInt16 nFirstPageNum = pPage->GetPhyPageNum();
540 :
541 57922 : while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
542 25630 : pPage = (SwPageFrm*)pPage->GetNext();
543 :
544 16146 : IDocumentLayoutAccess *pLayoutAccess = pRoot->GetFmt()->getIDocumentLayoutAccess();
545 16146 : sal_Bool bNoLoop = pPage ? SwLayouter::StartLoopControl( pRoot->GetFmt()->GetDoc(), pPage ) : sal_False;
546 16146 : sal_uInt16 nPercentPageNum = 0;
547 34943 : while ( (pPage && !IsInterrupt()) || nCheckPageNum != USHRT_MAX )
548 : {
549 5220 : if ( !pPage && nCheckPageNum != USHRT_MAX &&
550 0 : (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) )
551 : {
552 0 : if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum )
553 : {
554 0 : SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
555 0 : while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum )
556 0 : pPg = (SwPageFrm*)pPg->GetNext();
557 0 : if ( pPg )
558 0 : pPage = pPg;
559 0 : if ( !pPage )
560 0 : break;
561 : }
562 0 : SwPageFrm *pTmp = pPage->GetPrev() ?
563 0 : (SwPageFrm*)pPage->GetPrev() : pPage;
564 0 : SetCheckPages( sal_True );
565 0 : SwFrm::CheckPageDescs( pPage );
566 0 : SetCheckPages( sal_False );
567 0 : nCheckPageNum = USHRT_MAX;
568 0 : pPage = pTmp;
569 0 : continue;
570 : }
571 :
572 5220 : if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum )
573 : {
574 73 : nPercentPageNum = pPage->GetPhyPageNum();
575 73 : ::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell());
576 : }
577 5220 : pOptTab = 0;
578 : // No Shortcut for Idle or CalcLayout
579 5220 : if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) )
580 : {
581 3159 : pRoot->DeleteEmptySct();
582 3159 : XCHECKPAGE;
583 6908 : if ( !IsInterrupt() &&
584 6309 : (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
585 : {
586 590 : if ( pRoot->IsAssertFlyPages() )
587 587 : pRoot->AssertFlyPages();
588 590 : if ( pRoot->IsSuperfluous() )
589 : {
590 9 : sal_Bool bOld = IsAgain();
591 9 : pRoot->RemoveSuperfluous();
592 9 : bAgain = bOld;
593 : }
594 590 : if ( IsAgain() )
595 : {
596 0 : if( bNoLoop )
597 0 : pLayoutAccess->GetLayouter()->EndLoopControl();
598 0 : return;
599 : }
600 590 : pPage = (SwPageFrm*)pRoot->Lower();
601 1213 : while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
602 33 : pPage = (SwPageFrm*)pPage->GetNext();
603 1216 : while ( pPage && pPage->GetNext() &&
604 33 : pPage->GetPhyPageNum() < nFirstPageNum )
605 3 : pPage = (SwPageFrm*)pPage->GetNext();
606 590 : continue;
607 : }
608 2569 : break;
609 : }
610 : else
611 : {
612 2061 : pRoot->DeleteEmptySct();
613 2061 : XCHECKPAGE;
614 :
615 12343 : while ( !IsInterrupt() && !IsNextCycle() &&
616 4474 : ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) )
617 : {
618 2060 : unlockPositionOfObjects( pPage );
619 :
620 : // #i28701#
621 2060 : SwObjectFormatter::FormatObjsAtFrm( *pPage, *pPage, this );
622 2060 : if ( !IS_FLYS )
623 : {
624 : // If there are no (more) Flys, the flags are superfluous.
625 1872 : pPage->ValidateFlyLayout();
626 1872 : pPage->ValidateFlyCntnt();
627 : }
628 : // #i28701# - change condition
629 14197 : while ( !IsInterrupt() && !IsNextCycle() &&
630 6811 : ( pPage->IsInvalid() ||
631 2329 : (IS_FLYS && IS_INVAFLY) ) )
632 : {
633 : PROTOCOL( pPage, PROT_FILE_INIT, 0, 0)
634 2679 : XCHECKPAGE;
635 :
636 : // #i81146# new loop control
637 2679 : sal_uInt16 nLoopControlRuns_1 = 0;
638 2679 : const sal_uInt16 nLoopControlMax = 20;
639 :
640 6742 : while ( !IsNextCycle() && pPage->IsInvalidLayout() )
641 : {
642 1384 : pPage->ValidateLayout();
643 :
644 1384 : if ( ++nLoopControlRuns_1 > nLoopControlMax )
645 : {
646 : OSL_FAIL( "LoopControl_1 in SwLayAction::InternalAction" );
647 0 : break;
648 : }
649 :
650 1384 : FormatLayout( pPage );
651 1384 : XCHECKPAGE;
652 : }
653 : // #i28701# - change condition
654 8024 : if ( !IsNextCycle() &&
655 2744 : ( pPage->IsInvalidCntnt() ||
656 117 : (IS_FLYS && IS_INVAFLY) ) )
657 : {
658 2666 : pPage->ValidateFlyInCnt();
659 2666 : pPage->ValidateCntnt();
660 : // #i28701#
661 2666 : pPage->ValidateFlyLayout();
662 2666 : pPage->ValidateFlyCntnt();
663 2666 : if ( !FormatCntnt( pPage ) )
664 : {
665 227 : XCHECKPAGE;
666 227 : pPage->InvalidateCntnt();
667 227 : pPage->InvalidateFlyInCnt();
668 : // #i28701#
669 227 : pPage->InvalidateFlyLayout();
670 227 : pPage->InvalidateFlyCntnt();
671 227 : if ( IsBrowseActionStop() )
672 0 : bInput = sal_True;
673 : }
674 : }
675 2679 : if( bNoLoop )
676 2679 : pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
677 : }
678 :
679 2060 : unlockPositionOfObjects( pPage );
680 : }
681 :
682 : // A previous page may be invalid again.
683 2061 : XCHECKPAGE;
684 2061 : if ( !IS_FLYS )
685 : {
686 : // If there are no (more) Flys, the flags are superfluous.
687 1873 : pPage->ValidateFlyLayout();
688 1873 : pPage->ValidateFlyCntnt();
689 : }
690 2061 : if ( !IsInterrupt() )
691 : {
692 2041 : SetNextCycle( sal_False );
693 :
694 2041 : if ( nPreInvaPage != USHRT_MAX )
695 : {
696 2 : if( !IsComplete() && nPreInvaPage + 2 < nFirstPageNum )
697 : {
698 0 : pImp->SetFirstVisPageInvalid();
699 0 : SwPageFrm *pTmpPage = pImp->GetFirstVisPage();
700 0 : nFirstPageNum = pTmpPage->GetPhyPageNum();
701 0 : if( nPreInvaPage < nFirstPageNum )
702 : {
703 0 : nPreInvaPage = nFirstPageNum;
704 0 : pPage = pTmpPage;
705 : }
706 : }
707 6 : while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage )
708 2 : pPage = (SwPageFrm*)pPage->GetPrev();
709 2 : nPreInvaPage = USHRT_MAX;
710 : }
711 :
712 6661 : while ( pPage->GetPrev() &&
713 1031 : ( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() ||
714 505 : ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() &&
715 2093 : ((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) &&
716 41 : (((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >=
717 : nFirstPageNum) )
718 : {
719 1 : pPage = (SwPageFrm*)pPage->GetPrev();
720 : }
721 :
722 : // Continue to the next invalid page
723 10235 : while ( pPage && !pPage->IsInvalid() &&
724 2236 : (!IS_FLYS || !IS_INVAFLY) )
725 : {
726 2051 : pPage = (SwPageFrm*)pPage->GetNext();
727 : }
728 2041 : if( bNoLoop )
729 2041 : pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
730 : }
731 2061 : CheckIdleEnd();
732 : }
733 3988 : if ( !pPage && !IsInterrupt() &&
734 3283 : (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
735 : {
736 280 : if ( pRoot->IsAssertFlyPages() )
737 269 : pRoot->AssertFlyPages();
738 280 : if ( pRoot->IsSuperfluous() )
739 : {
740 11 : sal_Bool bOld = IsAgain();
741 11 : pRoot->RemoveSuperfluous();
742 11 : bAgain = bOld;
743 : }
744 280 : if ( IsAgain() )
745 : {
746 0 : if( bNoLoop )
747 0 : pLayoutAccess->GetLayouter()->EndLoopControl();
748 0 : return;
749 : }
750 280 : pPage = (SwPageFrm*)pRoot->Lower();
751 845 : while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
752 285 : pPage = (SwPageFrm*)pPage->GetNext();
753 568 : while ( pPage && pPage->GetNext() &&
754 4 : pPage->GetPhyPageNum() < nFirstPageNum )
755 4 : pPage = (SwPageFrm*)pPage->GetNext();
756 : }
757 : }
758 16146 : if ( IsInterrupt() && pPage )
759 : {
760 : // If we have input, we don't want to format content anymore, but
761 : // we still should clean the layout.
762 : // Otherwise, the following situation might arise:
763 : // The user enters some text at the end of the paragraph of the last
764 : // page, causing the paragraph to create a Follow for the next page.
765 : // Meanwhile the user continues typing, so we have input while
766 : // still formatting.
767 : // The paragraph on the new page has already been partially formatted,
768 : // and the new page has been fully formatted and is set to CompletePaint,
769 : // but hasn't added itself to the area to be output. Then we paint,
770 : // the CompletePaint of the page is reset because the new paragraph
771 : // already added itself, but the borders of the page haven't been painted
772 : // yet.
773 : // Oh well, with the inevitable following LayAction, the page doesn't
774 : // register itself, because it's (LayoutFrm) flags have been reset
775 : // already - the border of the page will never be painted.
776 20 : SwPageFrm *pPg = pPage;
777 20 : XCHECKPAGE;
778 20 : const SwRect &rVis = pImp->GetShell()->VisArea();
779 :
780 45 : while( pPg && pPg->Frm().Bottom() < rVis.Top() )
781 5 : pPg = (SwPageFrm*)pPg->GetNext();
782 20 : if( pPg != pPage )
783 2 : pPg = pPg ? (SwPageFrm*)pPg->GetPrev() : pPage;
784 :
785 : // set flag for interrupt content formatting
786 20 : mbFormatCntntOnInterrupt = IsInput() && !IsStopPrt();
787 20 : long nBottom = rVis.Bottom();
788 : // #i42586# - format current page, if idle action is active
789 : // This is an optimization for the case that the interrupt is created by
790 : // the move of a form control object, which is represented by a window.
791 105 : while ( pPg && ( pPg->Frm().Top() < nBottom ||
792 42 : ( IsIdle() && pPg == pPage ) ) )
793 : {
794 22 : unlockPositionOfObjects( pPg );
795 :
796 22 : XCHECKPAGE;
797 :
798 : // #i81146# new loop control
799 22 : sal_uInt16 nLoopControlRuns_2 = 0;
800 22 : const sal_uInt16 nLoopControlMax = 20;
801 :
802 : // special case: interrupt content formatting
803 : // #i28701# - conditions are incorrect (macros IS_FLYS and IS_INVAFLY only
804 : // works for <pPage>) and are too strict.
805 : // #i50432# - adjust interrupt formatting to normal page formatting - see above.
806 66 : while ( ( mbFormatCntntOnInterrupt &&
807 25 : ( pPg->IsInvalid() ||
808 48 : ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) ||
809 2 : ( !mbFormatCntntOnInterrupt && pPg->IsInvalidLayout() ) )
810 : {
811 20 : XCHECKPAGE;
812 : // #i50432# - format also at-page anchored objects
813 20 : SwObjectFormatter::FormatObjsAtFrm( *pPg, *pPg, this );
814 20 : if ( !pPg->GetSortedObjs() )
815 : {
816 17 : pPg->ValidateFlyLayout();
817 17 : pPg->ValidateFlyCntnt();
818 : }
819 :
820 : // #i81146# new loop control
821 20 : sal_uInt16 nLoopControlRuns_3 = 0;
822 :
823 40 : while ( pPg->IsInvalidLayout() )
824 : {
825 0 : pPg->ValidateLayout();
826 :
827 0 : if ( ++nLoopControlRuns_3 > nLoopControlMax )
828 : {
829 : OSL_FAIL( "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" );
830 0 : break;
831 : }
832 :
833 0 : FormatLayout( pPg );
834 0 : XCHECKPAGE;
835 : }
836 :
837 : // #i50432#
838 60 : if ( mbFormatCntntOnInterrupt &&
839 21 : ( pPg->IsInvalidCntnt() ||
840 2 : ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) )
841 : {
842 20 : pPg->ValidateFlyInCnt();
843 20 : pPg->ValidateCntnt();
844 : // #i26945#
845 20 : pPg->ValidateFlyLayout();
846 20 : pPg->ValidateFlyCntnt();
847 :
848 20 : if ( ++nLoopControlRuns_2 > nLoopControlMax )
849 : {
850 : OSL_FAIL( "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" );
851 0 : break;
852 : }
853 :
854 20 : if ( !FormatCntnt( pPg ) )
855 : {
856 0 : XCHECKPAGE;
857 0 : pPg->InvalidateCntnt();
858 0 : pPg->InvalidateFlyInCnt();
859 : // #i26945#
860 0 : pPg->InvalidateFlyLayout();
861 0 : pPg->InvalidateFlyCntnt();
862 : }
863 : // #i46807# - we are statisfied, if the content is formatted once complete.
864 : else
865 : {
866 20 : break;
867 : }
868 : }
869 : }
870 :
871 22 : unlockPositionOfObjects( pPg );
872 22 : pPg = (SwPageFrm*)pPg->GetNext();
873 : }
874 : // reset flag for special interrupt content formatting.
875 20 : mbFormatCntntOnInterrupt = sal_False;
876 : }
877 16146 : pOptTab = 0;
878 16146 : if( bNoLoop )
879 4237 : pLayoutAccess->GetLayouter()->EndLoopControl();
880 : }
881 : /*************************************************************************
882 : |*
883 : |* SwLayAction::TurboAction(), _TurboAction()
884 : |*
885 : |*************************************************************************/
886 4082 : sal_Bool SwLayAction::_TurboAction( const SwCntntFrm *pCnt )
887 : {
888 :
889 4082 : const SwPageFrm *pPage = 0;
890 4082 : if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() )
891 : {
892 4080 : const SwRect aOldRect( pCnt->UnionFrm( sal_True ) );
893 4080 : const long nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom();
894 4080 : pCnt->Calc();
895 4080 : if ( pCnt->Frm().Bottom() < aOldRect.Bottom() )
896 39 : pCnt->SetRetouche();
897 :
898 4080 : pPage = pCnt->FindPageFrm();
899 4080 : PaintCntnt( pCnt, pPage, aOldRect, nOldBottom );
900 :
901 4080 : if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() )
902 : {
903 179 : const sal_uLong nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines();
904 179 : ((SwTxtFrm*)pCnt)->RecalcAllLines();
905 179 : if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() )
906 : {
907 13 : if ( IsPaintExtraData() )
908 0 : pImp->GetShell()->AddPaintRect( pCnt->Frm() );
909 : // This is to calculate the remaining LineNums on the page,
910 : // and we don't stop processing here. To perform this inside RecalcAllLines
911 : // would be expensive, because we would have to notify the page even
912 : // in unnecessary cases (normal actions).
913 13 : const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
914 33 : while ( pNxt &&
915 14 : (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) )
916 0 : pNxt = pNxt->GetNextCntntFrm();
917 13 : if ( pNxt )
918 7 : pNxt->InvalidatePage();
919 : }
920 397 : return sal_False;
921 : }
922 :
923 3901 : if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) )
924 39 : return sal_False;
925 : }
926 3864 : if ( !pPage )
927 2 : pPage = pCnt->FindPageFrm();
928 :
929 : // OD 2004-05-10 #i28701# - format floating screen objects at content frame.
930 7724 : if ( pCnt->IsTxtFrm() &&
931 : !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCnt)),
932 3860 : *pPage, this ) )
933 : {
934 0 : return sal_False;
935 : }
936 :
937 3864 : if ( pPage->IsInvalidCntnt() )
938 423 : return sal_False;
939 3441 : return sal_True;
940 : }
941 :
942 16273 : sal_Bool SwLayAction::TurboAction()
943 : {
944 16273 : sal_Bool bRet = sal_True;
945 :
946 16273 : if ( pRoot->GetTurbo() )
947 : {
948 4082 : if ( !_TurboAction( pRoot->GetTurbo() ) )
949 : {
950 641 : CheckIdleEnd();
951 641 : bRet = sal_False;
952 : }
953 4082 : pRoot->ResetTurbo();
954 : }
955 : else
956 12191 : bRet = sal_False;
957 16273 : return bRet;
958 : }
959 : /*************************************************************************
960 : |*
961 : |* SwLayAction::IsShortCut()
962 : |*
963 : |* Description: Returns True if the page lies directly below or
964 : |* right of the visible area.
965 : |* It's possible for things to change in such a way that the processing
966 : |* (of the caller!) has to continue with the predecessor of the passed
967 : |* page. The parameter might therefore get modified!
968 : |* For BrowseMode, you may even activate the ShortCut if the invalid
969 : |* content of the page lies below the visible area.
970 : |*
971 : |*************************************************************************/
972 882 : static bool lcl_IsInvaLay( const SwFrm *pFrm, long nBottom )
973 : {
974 882 : if (
975 1767 : !pFrm->IsValid() ||
976 885 : (pFrm->IsCompletePaint() && ( pFrm->Frm().Top() < nBottom ) )
977 : )
978 : {
979 3 : return true;
980 : }
981 879 : return false;
982 : }
983 :
984 589 : static const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom )
985 : {
986 : OSL_ENSURE( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" );
987 :
988 589 : if (lcl_IsInvaLay(pFrm, nBottom))
989 3 : return pFrm;
990 586 : pFrm = ((SwLayoutFrm*)pFrm)->Lower();
991 1758 : while ( pFrm )
992 : {
993 586 : if ( pFrm->IsLayoutFrm() )
994 : {
995 293 : if (lcl_IsInvaLay(pFrm, nBottom))
996 0 : return pFrm;
997 : const SwFrm *pTmp;
998 293 : if ( 0 != (pTmp = lcl_FindFirstInvaLay( pFrm, nBottom )) )
999 0 : return pTmp;
1000 : }
1001 586 : pFrm = pFrm->GetNext();
1002 : }
1003 586 : return 0;
1004 : }
1005 :
1006 19 : static const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom,
1007 : const SwCntntFrm *pFirst )
1008 : {
1009 : const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() :
1010 19 : pLay->ContainsCntnt();
1011 38 : while ( pCnt )
1012 : {
1013 19 : if ( !pCnt->IsValid() || pCnt->IsCompletePaint() )
1014 : {
1015 19 : if ( pCnt->Frm().Top() <= nBottom )
1016 19 : return pCnt;
1017 : }
1018 :
1019 0 : if ( pCnt->GetDrawObjs() )
1020 : {
1021 0 : const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
1022 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1023 : {
1024 0 : const SwAnchoredObject* pObj = rObjs[i];
1025 0 : if ( pObj->ISA(SwFlyFrm) )
1026 : {
1027 0 : const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
1028 0 : if ( pFly->IsFlyInCntFrm() )
1029 : {
1030 0 : if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() ||
1031 0 : pFly->IsCompletePaint() )
1032 : {
1033 0 : if ( pFly->Frm().Top() <= nBottom )
1034 0 : return pFly;
1035 : }
1036 0 : const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 );
1037 0 : if ( pFrm && pFrm->Frm().Bottom() <= nBottom )
1038 0 : return pFrm;
1039 : }
1040 : }
1041 : }
1042 : }
1043 0 : if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() )
1044 0 : return 0;
1045 0 : pCnt = pCnt->GetNextCntntFrm();
1046 0 : if ( !pLay->IsAnLower( pCnt ) )
1047 0 : break;
1048 : }
1049 0 : return 0;
1050 : }
1051 :
1052 : // #i37877# - consider drawing objects
1053 0 : static const SwAnchoredObject* lcl_FindFirstInvaObj( const SwPageFrm* _pPage,
1054 : long _nBottom )
1055 : {
1056 : OSL_ENSURE( _pPage->GetSortedObjs(), "FindFirstInvaObj, no Objs" );
1057 :
1058 0 : for ( sal_uInt16 i = 0; i < _pPage->GetSortedObjs()->Count(); ++i )
1059 : {
1060 0 : const SwAnchoredObject* pObj = (*_pPage->GetSortedObjs())[i];
1061 0 : if ( pObj->ISA(SwFlyFrm) )
1062 : {
1063 0 : const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
1064 0 : if ( pFly->Frm().Top() <= _nBottom )
1065 : {
1066 0 : if ( pFly->IsInvalid() || pFly->IsCompletePaint() )
1067 0 : return pFly;
1068 :
1069 : const SwFrm* pTmp;
1070 0 : if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, _nBottom, 0 )) &&
1071 0 : pTmp->Frm().Top() <= _nBottom )
1072 0 : return pFly;
1073 : }
1074 : }
1075 0 : else if ( pObj->ISA(SwAnchoredDrawObject) )
1076 : {
1077 0 : if ( !static_cast<const SwAnchoredDrawObject*>(pObj)->IsValidPos() )
1078 : {
1079 0 : return pObj;
1080 : }
1081 : }
1082 : }
1083 0 : return 0;
1084 : }
1085 :
1086 5107 : sal_Bool SwLayAction::IsShortCut( SwPageFrm *&prPage )
1087 : {
1088 5107 : sal_Bool bRet = sal_False;
1089 5107 : const ViewShell *pSh = pRoot->GetCurrShell();
1090 5107 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1091 :
1092 : // If the page is not valid, we quickly format it, otherwise
1093 : // there's gonna be no end of trouble
1094 5107 : if ( !prPage->IsValid() )
1095 : {
1096 101 : if ( bBrowse )
1097 : {
1098 : /// OD 15.10.2002 #103517# - format complete page
1099 : /// Thus, loop on all lowers of the page <prPage>, instead of only
1100 : /// format its first lower.
1101 : /// NOTE: In online layout (bBrowse == true) a page can contain
1102 : /// a header frame and/or a footer frame beside the body frame.
1103 88 : prPage->Calc();
1104 88 : SwFrm* pPageLowerFrm = prPage->Lower();
1105 264 : while ( pPageLowerFrm )
1106 : {
1107 88 : pPageLowerFrm->Calc();
1108 88 : pPageLowerFrm = pPageLowerFrm->GetNext();
1109 : }
1110 : }
1111 : else
1112 13 : FormatLayout( prPage );
1113 101 : if ( IsAgain() )
1114 0 : return sal_False;
1115 : }
1116 :
1117 :
1118 5107 : const SwRect &rVis = pImp->GetShell()->VisArea();
1119 7317 : if ( (prPage->Frm().Top() >= rVis.Bottom()) ||
1120 2210 : (prPage->Frm().Left()>= rVis.Right()) )
1121 : {
1122 2897 : bRet = sal_True;
1123 :
1124 : // This is going to be a bit nasty: The first CntntFrm of this
1125 : // page in the Body text needs formatting; if it changes the page during
1126 : // that process, I need to start over a page further back, because we
1127 : // have been processing a PageBreak.
1128 : // Even more uncomfortable: The next CntntFrm must be formatted,
1129 : // because it's possible for empty pages to exist temporarily (for example
1130 : // a paragraph across multiple pages gets deleted or reduced in size).
1131 :
1132 : // This is irrelevant for the browser, if the last Cnt above it
1133 : // isn't visible anymore.
1134 :
1135 2897 : const SwPageFrm *p2ndPage = prPage;
1136 : const SwCntntFrm *pCntnt;
1137 2897 : const SwLayoutFrm* pBody = p2ndPage->FindBodyCont();
1138 2897 : if( p2ndPage->IsFtnPage() && pBody )
1139 35 : pBody = (SwLayoutFrm*)pBody->GetNext();
1140 2897 : pCntnt = pBody ? pBody->ContainsCntnt() : 0;
1141 5798 : while ( p2ndPage && !pCntnt )
1142 : {
1143 4 : p2ndPage = (SwPageFrm*)p2ndPage->GetNext();
1144 4 : if( p2ndPage )
1145 : {
1146 0 : pBody = p2ndPage->FindBodyCont();
1147 0 : if( p2ndPage->IsFtnPage() && pBody )
1148 0 : pBody = (SwLayoutFrm*)pBody->GetNext();
1149 0 : pCntnt = pBody ? pBody->ContainsCntnt() : 0;
1150 : }
1151 : }
1152 2897 : if ( pCntnt )
1153 : {
1154 2893 : bool bTstCnt = true;
1155 2893 : if ( bBrowse )
1156 : {
1157 : // Is the Cnt before already invisible?
1158 6 : const SwFrm *pLst = pCntnt;
1159 6 : if ( pLst->IsInTab() )
1160 0 : pLst = pCntnt->FindTabFrm();
1161 6 : if ( pLst->IsInSct() )
1162 0 : pLst = pCntnt->FindSctFrm();
1163 6 : pLst = pLst->FindPrev();
1164 6 : if ( pLst &&
1165 0 : (pLst->Frm().Top() >= rVis.Bottom() ||
1166 0 : pLst->Frm().Left()>= rVis.Right()) )
1167 : {
1168 0 : bTstCnt = false;
1169 : }
1170 : }
1171 :
1172 2893 : if ( bTstCnt )
1173 : {
1174 : // #i27756# - check after each frame calculation,
1175 : // if the content frame has changed the page. If yes, no other
1176 : // frame calculation is performed
1177 2893 : bool bPageChg = false;
1178 :
1179 2893 : if ( pCntnt->IsInSct() )
1180 : {
1181 37 : const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
1182 37 : if ( !pSct->IsValid() )
1183 : {
1184 14 : pSct->Calc();
1185 14 : pSct->SetCompletePaint();
1186 14 : if ( IsAgain() )
1187 0 : return sal_False;
1188 : // #i27756#
1189 15 : bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1190 15 : prPage->GetPrev();
1191 : }
1192 : }
1193 :
1194 2893 : if ( !bPageChg && !pCntnt->IsValid() )
1195 : {
1196 474 : pCntnt->Calc();
1197 474 : pCntnt->SetCompletePaint();
1198 474 : if ( IsAgain() )
1199 0 : return sal_False;
1200 : // #i27756#
1201 485 : bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1202 485 : prPage->GetPrev();
1203 : }
1204 :
1205 2893 : if ( !bPageChg && pCntnt->IsInTab() )
1206 : {
1207 98 : const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm();
1208 98 : if ( !pTab->IsValid() )
1209 : {
1210 19 : pTab->Calc();
1211 19 : pTab->SetCompletePaint();
1212 19 : if ( IsAgain() )
1213 0 : return sal_False;
1214 : // #i27756#
1215 19 : bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1216 19 : prPage->GetPrev();
1217 : }
1218 : }
1219 :
1220 2893 : if ( !bPageChg && pCntnt->IsInSct() )
1221 : {
1222 29 : const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
1223 29 : if ( !pSct->IsValid() )
1224 : {
1225 0 : pSct->Calc();
1226 0 : pSct->SetCompletePaint();
1227 0 : if ( IsAgain() )
1228 0 : return sal_False;
1229 : // #i27756#
1230 0 : bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
1231 0 : prPage->GetPrev();
1232 : }
1233 : }
1234 :
1235 : // #i27756#
1236 2893 : if ( bPageChg )
1237 : {
1238 12 : bRet = sal_False;
1239 12 : const SwPageFrm* pTmp = pCntnt->FindPageFrm();
1240 24 : if ( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() &&
1241 12 : pTmp->IsInvalid() )
1242 : {
1243 12 : prPage = (SwPageFrm*)pTmp;
1244 : }
1245 : else
1246 : {
1247 0 : prPage = (SwPageFrm*)prPage->GetPrev();
1248 : }
1249 : }
1250 : // #121980# - no shortcut, if at previous page
1251 : // an anchored object is registered, whose anchor is <pCntnt>.
1252 3349 : else if ( prPage->GetPrev() &&
1253 468 : static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs() )
1254 : {
1255 : SwSortedObjs* pObjs =
1256 65 : static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs();
1257 65 : if ( pObjs )
1258 : {
1259 65 : sal_uInt32 i = 0;
1260 163 : for ( ; i < pObjs->Count(); ++i )
1261 : {
1262 98 : SwAnchoredObject* pObj = (*pObjs)[i];
1263 98 : if ( pObj->GetAnchorFrmContainingAnchPos() == pCntnt )
1264 : {
1265 0 : bRet = sal_False;
1266 0 : break;
1267 : }
1268 : }
1269 : }
1270 : }
1271 : }
1272 : }
1273 : }
1274 :
1275 5107 : if ( !bRet && bBrowse )
1276 : {
1277 296 : const long nBottom = rVis.Bottom();
1278 296 : const SwAnchoredObject* pObj( 0L );
1279 1184 : if ( prPage->GetSortedObjs() &&
1280 0 : (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) &&
1281 592 : 0 != (pObj = lcl_FindFirstInvaObj( prPage, nBottom )) &&
1282 296 : pObj->GetObjRect().Top() <= nBottom )
1283 : {
1284 0 : return sal_False;
1285 : }
1286 296 : const SwFrm* pFrm( 0L );
1287 888 : if ( prPage->IsInvalidLayout() &&
1288 299 : 0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) &&
1289 3 : pFrm->Frm().Top() <= nBottom )
1290 : {
1291 3 : return sal_False;
1292 : }
1293 879 : if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) &&
1294 331 : 0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) &&
1295 19 : pFrm->Frm().Top() <= nBottom )
1296 : {
1297 19 : return sal_False;
1298 : }
1299 274 : bRet = sal_True;
1300 : }
1301 5085 : return bRet;
1302 : }
1303 :
1304 : /*************************************************************************
1305 : |*
1306 : |* SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab()
1307 : |*
1308 : |*************************************************************************/
1309 : // OD 15.11.2002 #105155# - introduce support for vertical layout
1310 9648 : sal_Bool SwLayAction::FormatLayout( SwLayoutFrm *pLay, sal_Bool bAddRect )
1311 : {
1312 : OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
1313 9648 : if ( IsAgain() )
1314 0 : return sal_False;
1315 :
1316 9648 : sal_Bool bChanged = sal_False;
1317 9648 : bool bAlreadyPainted = false;
1318 : // OD 11.11.2002 #104414# - remember frame at complete paint
1319 9648 : SwRect aFrmAtCompletePaint;
1320 :
1321 9648 : if ( !pLay->IsValid() || pLay->IsCompletePaint() )
1322 : {
1323 5370 : if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() )
1324 328 : pLay->GetPrev()->SetCompletePaint();
1325 :
1326 5370 : SwRect aOldFrame( pLay->Frm() );
1327 5370 : SwRect aOldRect( aOldFrame );
1328 5370 : if( pLay->IsPageFrm() )
1329 : {
1330 902 : aOldRect = static_cast<SwPageFrm*>(pLay)->GetBoundRect();
1331 : }
1332 :
1333 5370 : pLay->Calc();
1334 5370 : if ( aOldFrame != pLay->Frm() )
1335 1645 : bChanged = sal_True;
1336 :
1337 5370 : bool bNoPaint = false;
1338 11707 : if ( pLay->IsPageBodyFrm() &&
1339 6317 : pLay->Frm().Pos() == aOldRect.Pos() &&
1340 947 : pLay->Lower() )
1341 : {
1342 938 : const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
1343 : // Limitations because of headers / footers
1344 944 : if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
1345 6 : !( pLay->IsCompletePaint() && pLay->FindPageFrm()->FindFtnCont() ) )
1346 3 : bNoPaint = true;
1347 : }
1348 :
1349 5370 : if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) )
1350 : {
1351 363 : SwRect aPaint( pLay->Frm() );
1352 : // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for
1353 : // page frames -> enlarge paint rectangle correspondingly.
1354 363 : if ( pLay->IsPageFrm() )
1355 : {
1356 45 : SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay);
1357 45 : aPaint = pPageFrm->GetBoundRect();
1358 : }
1359 :
1360 363 : bool bPageInBrowseMode = pLay->IsPageFrm();
1361 363 : if( bPageInBrowseMode )
1362 : {
1363 45 : const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
1364 45 : if( !pSh || !pSh->GetViewOptions()->getBrowseMode() )
1365 41 : bPageInBrowseMode = false;
1366 : }
1367 363 : if( bPageInBrowseMode )
1368 : {
1369 : // NOTE: no vertical layout in online layout
1370 : // Is the change even visible?
1371 4 : if ( pLay->IsCompletePaint() )
1372 : {
1373 4 : pImp->GetShell()->AddPaintRect( aPaint );
1374 4 : bAddRect = sal_False;
1375 : }
1376 : else
1377 : {
1378 : sal_uInt16 i;
1379 :
1380 0 : SwRegionRects aRegion( aOldRect );
1381 0 : aRegion -= aPaint;
1382 0 : for ( i = 0; i < aRegion.size(); ++i )
1383 0 : pImp->GetShell()->AddPaintRect( aRegion[i] );
1384 0 : aRegion.ChangeOrigin( aPaint );
1385 0 : aRegion.clear();
1386 0 : aRegion.push_back( aPaint );
1387 0 : aRegion -= aOldRect;
1388 0 : for ( i = 0; i < aRegion.size(); ++i )
1389 0 : pImp->GetShell()->AddPaintRect( aRegion[i] );
1390 : }
1391 :
1392 : }
1393 : else
1394 : {
1395 359 : pImp->GetShell()->AddPaintRect( aPaint );
1396 359 : bAlreadyPainted = true;
1397 : // OD 11.11.2002 #104414# - remember frame at complete paint
1398 359 : aFrmAtCompletePaint = pLay->Frm();
1399 : }
1400 :
1401 : // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing
1402 : // between pages (not only for in online mode).
1403 363 : if ( pLay->IsPageFrm() )
1404 : {
1405 45 : const SwTwips nHalfDocBorder = GAPBETWEENPAGES;
1406 45 : const bool bLeftToRightViewLayout = pRoot->IsLeftToRightViewLayout();
1407 45 : const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext();
1408 45 : const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev();
1409 45 : SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay);
1410 45 : const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
1411 45 : SwRect aPageRect( pLay->Frm() );
1412 :
1413 45 : if(pSh)
1414 : {
1415 : SwPageFrm::GetBorderAndShadowBoundRect(aPageRect, pSh,
1416 90 : aPageRect, pPageFrm->IsLeftShadowNeeded(), pPageFrm->IsRightShadowNeeded(),
1417 135 : pPageFrm->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
1418 : }
1419 :
1420 45 : if ( bPrev )
1421 : {
1422 : // top
1423 19 : SwRect aSpaceToPrevPage( aPageRect );
1424 19 : aSpaceToPrevPage.Top( aSpaceToPrevPage.Top() - nHalfDocBorder );
1425 19 : aSpaceToPrevPage.Bottom( pLay->Frm().Top() );
1426 19 : if(aSpaceToPrevPage.Height() > 0 && aSpaceToPrevPage.Width() > 0)
1427 19 : pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
1428 :
1429 19 : pSh->GetOut()->DrawRect( aSpaceToPrevPage.SVRect() );
1430 :
1431 : // left
1432 19 : aSpaceToPrevPage = aPageRect;
1433 19 : aSpaceToPrevPage.Left( aSpaceToPrevPage.Left() - nHalfDocBorder );
1434 19 : aSpaceToPrevPage.Right( pLay->Frm().Left() );
1435 19 : if(aSpaceToPrevPage.Height() > 0 && aSpaceToPrevPage.Width() > 0)
1436 19 : pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
1437 : }
1438 45 : if ( bNext )
1439 : {
1440 : // bottom
1441 10 : SwRect aSpaceToNextPage( aPageRect );
1442 10 : aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder );
1443 10 : aSpaceToNextPage.Top( pLay->Frm().Bottom() );
1444 10 : if(aSpaceToNextPage.Height() > 0 && aSpaceToNextPage.Width() > 0)
1445 10 : pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
1446 :
1447 : // right
1448 10 : aSpaceToNextPage = aPageRect;
1449 10 : aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder );
1450 10 : aSpaceToNextPage.Left( pLay->Frm().Right() );
1451 10 : if(aSpaceToNextPage.Height() > 0 && aSpaceToNextPage.Width() > 0)
1452 10 : pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
1453 : }
1454 : }
1455 : }
1456 5370 : pLay->ResetCompletePaint();
1457 : }
1458 :
1459 26507 : if ( IsPaint() && bAddRect &&
1460 14010 : !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() )
1461 : {
1462 : // OD 15.11.2002 #105155# - vertical layout support
1463 9 : SWRECTFN( pLay );
1464 9 : SwRect aRect( pLay->GetUpper()->PaintArea() );
1465 9 : (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() );
1466 9 : if ( !pImp->GetShell()->AddPaintRect( aRect ) )
1467 8 : pLay->ResetRetouche();
1468 : }
1469 :
1470 9648 : if( bAlreadyPainted )
1471 359 : bAddRect = sal_False;
1472 :
1473 9648 : CheckWaitCrsr();
1474 :
1475 9648 : if ( IsAgain() )
1476 0 : return sal_False;
1477 :
1478 : // Now, deal with the lowers that are LayoutFrms
1479 :
1480 9648 : if ( pLay->IsFtnFrm() ) // no LayFrms as Lower
1481 81 : return bChanged;
1482 :
1483 9567 : SwFrm *pLow = pLay->Lower();
1484 9567 : sal_Bool bTabChanged = sal_False;
1485 35488 : while ( pLow && pLow->GetUpper() == pLay )
1486 : {
1487 16354 : if ( pLow->IsLayoutFrm() )
1488 : {
1489 7338 : if ( pLow->IsTabFrm() )
1490 458 : bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
1491 : // Skip the ones already registered for deletion
1492 6880 : else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() )
1493 6880 : bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
1494 : }
1495 9016 : else if ( pImp->GetShell()->IsPaintLocked() )
1496 : // Shortcut to minimize the cycles. With Lock, the
1497 : // paint is coming either way (primarily for browse)
1498 4271 : pLow->OptCalc();
1499 :
1500 16354 : if ( IsAgain() )
1501 0 : return sal_False;
1502 16354 : pLow = pLow->GetNext();
1503 : }
1504 : // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame
1505 : // area has been already added and after formating its lowers the frame area
1506 : // is enlarged.
1507 9567 : SwRect aBoundRect(pLay->IsPageFrm() ? static_cast<SwPageFrm*>(pLay)->GetBoundRect() : pLay->Frm() );
1508 :
1509 9967 : if ( bAlreadyPainted &&
1510 677 : ( aBoundRect.Width() > aFrmAtCompletePaint.Width() ||
1511 318 : aBoundRect.Height() > aFrmAtCompletePaint.Height() )
1512 : )
1513 : {
1514 41 : pImp->GetShell()->AddPaintRect( aBoundRect );
1515 : }
1516 9567 : return bChanged || bTabChanged;
1517 : }
1518 :
1519 712 : sal_Bool SwLayAction::FormatLayoutFly( SwFlyFrm* pFly )
1520 : {
1521 : OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
1522 712 : if ( IsAgain() )
1523 0 : return sal_False;
1524 :
1525 712 : sal_Bool bChanged = false;
1526 712 : sal_Bool bAddRect = true;
1527 :
1528 712 : if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() )
1529 : {
1530 : // The Frame has changed, now it's getting formatted.
1531 520 : const SwRect aOldRect( pFly->Frm() );
1532 520 : pFly->Calc();
1533 520 : bChanged = aOldRect != pFly->Frm();
1534 :
1535 1323 : if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) &&
1536 766 : pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
1537 117 : pImp->GetShell()->AddPaintRect( pFly->Frm() );
1538 :
1539 520 : if ( bChanged )
1540 149 : pFly->Invalidate();
1541 : else
1542 371 : pFly->Validate();
1543 : /*
1544 : //mba: it's unclear why we should invalidate always, so I remove it
1545 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1546 : if ( IsPaint() && bAddRect && pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
1547 : pImp->GetShell()->AddPaintRect( pFly->Frm() );
1548 :
1549 : pFly->Invalidate();
1550 : */
1551 520 : bAddRect = false;
1552 520 : pFly->ResetCompletePaint();
1553 : }
1554 :
1555 712 : if ( IsAgain() )
1556 0 : return sal_False;
1557 :
1558 : // Now, deal with the lowers that are LayoutFrms
1559 712 : sal_Bool bTabChanged = false;
1560 712 : SwFrm *pLow = pFly->Lower();
1561 2201 : while ( pLow )
1562 : {
1563 777 : if ( pLow->IsLayoutFrm() )
1564 : {
1565 32 : if ( pLow->IsTabFrm() )
1566 32 : bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
1567 : else
1568 0 : bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
1569 : }
1570 777 : pLow = pLow->GetNext();
1571 : }
1572 712 : return bChanged || bTabChanged;
1573 : }
1574 :
1575 : // OD 31.10.2002 #104100#
1576 : // Implement vertical layout support
1577 490 : sal_Bool SwLayAction::FormatLayoutTab( SwTabFrm *pTab, sal_Bool bAddRect )
1578 : {
1579 : OSL_ENSURE( !IsAgain(), "8-) Attention to the invalid page." );
1580 490 : if ( IsAgain() || !pTab->Lower() )
1581 0 : return sal_False;
1582 :
1583 490 : IDocumentTimerAccess *pTimerAccess = pRoot->GetFmt()->getIDocumentTimerAccess();
1584 490 : pTimerAccess->BlockIdling();
1585 :
1586 490 : sal_Bool bChanged = sal_False;
1587 490 : bool bPainted = false;
1588 :
1589 490 : const SwPageFrm *pOldPage = pTab->FindPageFrm();
1590 :
1591 : // OD 31.10.2002 #104100# - vertical layout support
1592 : // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and
1593 : // <SwRectFn fnRect> for table frame <pTab>.
1594 490 : SWRECTFN( pTab );
1595 :
1596 490 : if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() )
1597 : {
1598 388 : if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() )
1599 : {
1600 13 : pTab->GetPrev()->SetCompletePaint();
1601 : }
1602 :
1603 388 : const SwRect aOldRect( pTab->Frm() );
1604 388 : pTab->SetLowersFormatted( sal_False );
1605 388 : pTab->Calc();
1606 388 : if ( aOldRect != pTab->Frm() )
1607 : {
1608 121 : bChanged = sal_True;
1609 : }
1610 388 : const SwRect aPaintFrm = pTab->PaintArea();
1611 :
1612 388 : if ( IsPaint() && bAddRect )
1613 : {
1614 : // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()>
1615 278 : if ( !pTab->IsCompletePaint() &&
1616 120 : pTab->IsComplete() &&
1617 58 : ( pTab->Frm().SSize() != pTab->Prt().SSize() ||
1618 : // OD 31.10.2002 #104100# - vertical layout support
1619 166 : (pTab->*fnRect->fnGetLeftMargin)() ) &&
1620 58 : pTab->Frm().HasArea()
1621 : )
1622 : {
1623 : // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles.
1624 58 : SwRect aMarginRect;
1625 :
1626 58 : SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)();
1627 58 : if ( nLeftMargin > 0)
1628 : {
1629 0 : aMarginRect = pTab->Frm();
1630 0 : (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin );
1631 0 : pImp->GetShell()->AddPaintRect( aMarginRect );
1632 : }
1633 :
1634 58 : if ( (pTab->*fnRect->fnGetRightMargin)() > 0)
1635 : {
1636 1 : aMarginRect = pTab->Frm();
1637 1 : (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() );
1638 1 : pImp->GetShell()->AddPaintRect( aMarginRect );
1639 : }
1640 :
1641 58 : SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)();
1642 58 : if ( nTopMargin > 0)
1643 : {
1644 1 : aMarginRect = pTab->Frm();
1645 1 : (aMarginRect.*fnRect->fnSetHeight)( nTopMargin );
1646 1 : pImp->GetShell()->AddPaintRect( aMarginRect );
1647 : }
1648 :
1649 58 : if ( (pTab->*fnRect->fnGetBottomMargin)() > 0)
1650 : {
1651 58 : aMarginRect = pTab->Frm();
1652 58 : (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
1653 58 : pImp->GetShell()->AddPaintRect( aMarginRect );
1654 : }
1655 : }
1656 50 : else if ( pTab->IsCompletePaint() )
1657 : {
1658 46 : pImp->GetShell()->AddPaintRect( aPaintFrm );
1659 46 : bAddRect = sal_False;
1660 46 : bPainted = true;
1661 : }
1662 :
1663 108 : if ( pTab->IsRetouche() && !pTab->GetNext() )
1664 : {
1665 0 : SwRect aRect( pTab->GetUpper()->PaintArea() );
1666 : // OD 04.11.2002 #104100# - vertical layout support
1667 0 : (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
1668 0 : if ( !pImp->GetShell()->AddPaintRect( aRect ) )
1669 0 : pTab->ResetRetouche();
1670 : }
1671 : }
1672 : else
1673 280 : bAddRect = sal_False;
1674 :
1675 388 : if ( pTab->IsCompletePaint() && !pOptTab )
1676 114 : pOptTab = pTab;
1677 388 : pTab->ResetCompletePaint();
1678 : }
1679 490 : if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() )
1680 : {
1681 : // OD 04.10.2002 #102779#
1682 : // set correct rectangle for retouche: area between bottom of table frame
1683 : // and bottom of paint area of the upper frame.
1684 0 : SwRect aRect( pTab->GetUpper()->PaintArea() );
1685 : // OD 04.11.2002 #104100# - vertical layout support
1686 0 : (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
1687 0 : if ( !pImp->GetShell()->AddPaintRect( aRect ) )
1688 0 : pTab->ResetRetouche();
1689 : }
1690 :
1691 490 : CheckWaitCrsr();
1692 :
1693 490 : pTimerAccess->UnblockIdling();
1694 :
1695 : // Ugly shortcut!
1696 494 : if ( pTab->IsLowersFormatted() &&
1697 0 : (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) )
1698 4 : return sal_False;
1699 :
1700 : // Now, deal with the lowers
1701 486 : if ( IsAgain() )
1702 0 : return sal_False;
1703 :
1704 : // OD 20.10.2003 #112464# - for savety reasons:
1705 : // check page number before formatting lowers.
1706 486 : if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) )
1707 0 : SetNextCycle( sal_True );
1708 :
1709 : // OD 20.10.2003 #112464# - format lowers, only if table frame is valid
1710 486 : if ( pTab->IsValid() )
1711 : {
1712 486 : SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower();
1713 2343 : while ( pLow )
1714 : {
1715 1371 : bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
1716 1371 : if ( IsAgain() )
1717 0 : return sal_False;
1718 1371 : pLow = (SwLayoutFrm*)pLow->GetNext();
1719 : }
1720 : }
1721 :
1722 486 : return bChanged;
1723 : }
1724 :
1725 : /*************************************************************************
1726 : |*
1727 : |* SwLayAction::FormatCntnt()
1728 : |*
1729 : |*************************************************************************/
1730 2686 : sal_Bool SwLayAction::FormatCntnt( const SwPageFrm *pPage )
1731 : {
1732 2686 : const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
1733 2686 : const ViewShell *pSh = pRoot->GetCurrShell();
1734 2686 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1735 :
1736 17048 : while ( pCntnt && pPage->IsAnLower( pCntnt ) )
1737 : {
1738 : // If the Cntnt didn't change, we can use a few shortcuts.
1739 23742 : const bool bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() ||
1740 18795 : pCntnt->IsRetouche() || pCntnt->GetDrawObjs();
1741 11903 : if ( bFull )
1742 : {
1743 : // We do this so we don't have to search later on.
1744 8631 : const bool bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow();
1745 8631 : const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0;
1746 8631 : const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0;
1747 :
1748 8631 : const SwLayoutFrm*pOldUpper = pCntnt->GetUpper();
1749 8631 : const SwTabFrm *pTab = pCntnt->FindTabFrm();
1750 8631 : const bool bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint();
1751 8631 : const sal_Bool bOldPaint = IsPaint();
1752 8631 : bPaint = bOldPaint && !(pTab && pTab == pOptTab);
1753 8631 : _FormatCntnt( pCntnt, pPage );
1754 : // #i26945# - reset <bPaint> before format objects
1755 8631 : bPaint = bOldPaint;
1756 :
1757 : // OD 2004-05-10 #i28701# - format floating screen object at content frame.
1758 : // No format, if action flag <bAgain> is set or action is interrupted.
1759 : // OD 2004-08-30 #117736# - allow format on interruption of action, if
1760 : // it's the format for this interrupt
1761 : // #i23129#, #i36347# - pass correct page frame
1762 : // to the object formatter.
1763 25893 : if ( !IsAgain() &&
1764 17366 : ( !IsInterrupt() || mbFormatCntntOnInterrupt ) &&
1765 25893 : pCntnt->IsTxtFrm() &&
1766 : !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCntnt)),
1767 8631 : *(pCntnt->FindPageFrm()), this ) )
1768 : {
1769 23 : return sal_False;
1770 : }
1771 :
1772 8608 : if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
1773 : {
1774 5645 : const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
1775 5645 : ((SwTxtFrm*)pCntnt)->RecalcAllLines();
1776 5651 : if ( IsPaintExtraData() && IsPaint() &&
1777 6 : nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
1778 1 : pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
1779 : }
1780 :
1781 8608 : if ( IsAgain() )
1782 0 : return sal_False;
1783 :
1784 : // Temporarily interrupt processing if layout or Flys become invalid again.
1785 : // However not for the BrowseView: The layout is getting invalid
1786 : // all the time because the page height gets adjusted.
1787 : // The same applies if the user wants to continue working and at least one
1788 : // paragraph has been processed.
1789 8608 : if ( (!pTab || (pTab && !bInValid)) )
1790 : {
1791 4875 : CheckIdleEnd();
1792 : // OD 14.04.2003 #106346# - consider interrupt formatting.
1793 14705 : if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) ||
1794 19548 : ( !bBrowse && pPage->IsInvalidLayout() ) ||
1795 : // OD 07.05.2003 #109435# - consider interrupt formatting
1796 5836 : ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt )
1797 : )
1798 203 : return sal_False;
1799 : }
1800 8405 : if ( pOldUpper != pCntnt->GetUpper() )
1801 : {
1802 11 : const sal_uInt16 nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum();
1803 11 : if ( nCurNum < pPage->GetPhyPageNum() )
1804 2 : nPreInvaPage = nCurNum;
1805 :
1806 : // If the Frm flowed backwards more than one page, we need to
1807 : // start over again from the beginning, so nothing gets left out.
1808 11 : if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 )
1809 : {
1810 0 : SetNextCycle( sal_True );
1811 : // OD 07.05.2003 #109435# - consider interrupt formatting
1812 0 : if ( !mbFormatCntntOnInterrupt )
1813 : {
1814 0 : return sal_False;
1815 : }
1816 : }
1817 : }
1818 : // If the Frame moved forwards to the next page, we re-run through
1819 : // the predecessor.
1820 : // This way, we catch predecessors which are now responsible for
1821 : // retouching, but the footers will be touched also.
1822 8405 : bool bSetCntnt = true;
1823 8405 : if ( pCntntPrev )
1824 : {
1825 3002 : if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) )
1826 10 : pPage->InvalidateCntnt();
1827 3011 : if ( pOldUpper != pCntnt->GetUpper() &&
1828 9 : pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() )
1829 : {
1830 9 : pCntnt = pCntntPrev;
1831 9 : bSetCntnt = false;
1832 : }
1833 : }
1834 8405 : if ( bSetCntnt )
1835 : {
1836 8415 : if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1837 19 : pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
1838 : {
1839 0 : const long nBottom = pImp->GetShell()->VisArea().Bottom();
1840 : const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
1841 0 : nBottom, pCntnt );
1842 0 : if ( !pTmp )
1843 : {
1844 0 : if ( (!(IS_FLYS && IS_INVAFLY) ||
1845 0 : !lcl_FindFirstInvaObj( pPage, nBottom )) &&
1846 0 : (!pPage->IsInvalidLayout() ||
1847 0 : !lcl_FindFirstInvaLay( pPage, nBottom )))
1848 0 : SetBrowseActionStop( sal_True );
1849 : // OD 14.04.2003 #106346# - consider interrupt formatting.
1850 0 : if ( !mbFormatCntntOnInterrupt )
1851 : {
1852 0 : return sal_False;
1853 : }
1854 : }
1855 : }
1856 8396 : pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm();
1857 : }
1858 :
1859 8405 : RESCHEDULE;
1860 : }
1861 : else
1862 : {
1863 3272 : if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
1864 : {
1865 12 : const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
1866 12 : ((SwTxtFrm*)pCntnt)->RecalcAllLines();
1867 12 : if ( IsPaintExtraData() && IsPaint() &&
1868 0 : nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
1869 0 : pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
1870 : }
1871 :
1872 : // Do this if the Frm has been formatted before.
1873 3347 : if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() &&
1874 75 : IsPaint() )
1875 75 : PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom());
1876 3272 : if ( IsIdle() )
1877 : {
1878 28 : CheckIdleEnd();
1879 : // OD 14.04.2003 #106346# - consider interrupt formatting.
1880 28 : if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
1881 1 : return sal_False;
1882 : }
1883 3278 : if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1884 7 : pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
1885 : {
1886 0 : const long nBottom = pImp->GetShell()->VisArea().Bottom();
1887 : const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
1888 0 : nBottom, pCntnt );
1889 0 : if ( !pTmp )
1890 : {
1891 0 : if ( (!(IS_FLYS && IS_INVAFLY) ||
1892 0 : !lcl_FindFirstInvaObj( pPage, nBottom )) &&
1893 0 : (!pPage->IsInvalidLayout() ||
1894 0 : !lcl_FindFirstInvaLay( pPage, nBottom )))
1895 0 : SetBrowseActionStop( sal_True );
1896 : // OD 14.04.2003 #106346# - consider interrupt formatting.
1897 0 : if ( !mbFormatCntntOnInterrupt )
1898 : {
1899 0 : return sal_False;
1900 : }
1901 : }
1902 : }
1903 3271 : pCntnt = pCntnt->GetNextCntntFrm();
1904 : }
1905 : }
1906 2459 : CheckWaitCrsr();
1907 : // OD 14.04.2003 #106346# - consider interrupt formatting.
1908 2459 : return !IsInterrupt() || mbFormatCntntOnInterrupt;
1909 : }
1910 : /*************************************************************************
1911 : |*
1912 : |* SwLayAction::_FormatCntnt()
1913 : |*
1914 : |* Description Returns sal_True if the paragraph has been processed,
1915 : |* sal_False if there wasn't anything to be processed.
1916 : |*
1917 : |*************************************************************************/
1918 9616 : void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt,
1919 : const SwPageFrm *pPage )
1920 : {
1921 : // We probably only ended up here because the Cntnt holds DrawObjects.
1922 9999 : const bool bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() &&
1923 9999 : !pCntnt->IsRetouche();
1924 9616 : SWRECTFN( pCntnt )
1925 9616 : if ( !bDrawObjsOnly && IsPaint() )
1926 : {
1927 4624 : const SwRect aOldRect( pCntnt->UnionFrm() );
1928 4624 : const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)();
1929 4624 : pCntnt->OptCalc();
1930 4624 : if( IsAgain() )
1931 9616 : return;
1932 13872 : if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(),
1933 13872 : (aOldRect.*fnRect->fnGetBottom)() ) < 0 )
1934 : {
1935 104 : pCntnt->SetRetouche();
1936 : }
1937 4624 : PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom);
1938 : }
1939 : else
1940 : {
1941 4992 : if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() )
1942 9 : PaintCntnt( pCntnt, pPage, pCntnt->Frm(),
1943 18 : (pCntnt->Frm().*fnRect->fnGetBottom)() );
1944 4992 : pCntnt->OptCalc();
1945 : }
1946 : }
1947 :
1948 : /*************************************************************************
1949 : |*
1950 : |* SwLayAction::_FormatFlyCntnt()
1951 : |*
1952 : |* Description:
1953 : |* - Returns sal_True if all Cntnts of the Fly have been processed completely.
1954 : |* Returns sal_False if processing has been interrupted prematurely.
1955 : |*
1956 : |*************************************************************************/
1957 712 : sal_Bool SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly )
1958 : {
1959 712 : const SwCntntFrm *pCntnt = pFly->ContainsCntnt();
1960 :
1961 2407 : while ( pCntnt )
1962 : {
1963 : // OD 2004-05-10 #i28701#
1964 985 : _FormatCntnt( pCntnt, pCntnt->FindPageFrm() );
1965 :
1966 : // #i28701# - format floating screen objects
1967 : // at content text frame
1968 : // #i23129#, #i36347# - pass correct page frame
1969 : // to the object formatter.
1970 1697 : if ( pCntnt->IsTxtFrm() &&
1971 : !SwObjectFormatter::FormatObjsAtFrm(
1972 : *(const_cast<SwCntntFrm*>(pCntnt)),
1973 712 : *(pCntnt->FindPageFrm()), this ) )
1974 : {
1975 : // restart format with first content
1976 0 : pCntnt = pFly->ContainsCntnt();
1977 0 : continue;
1978 : }
1979 :
1980 985 : if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
1981 : {
1982 255 : const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
1983 255 : ((SwTxtFrm*)pCntnt)->RecalcAllLines();
1984 255 : if ( IsPaintExtraData() && IsPaint() &&
1985 0 : nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
1986 0 : pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
1987 : }
1988 :
1989 985 : if ( IsAgain() )
1990 0 : return sal_False;
1991 :
1992 : // If there's input, we interrupt processing.
1993 985 : if ( !pFly->IsFlyInCntFrm() )
1994 : {
1995 735 : CheckIdleEnd();
1996 : // OD 14.04.2003 #106346# - consider interrupt formatting.
1997 735 : if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
1998 2 : return sal_False;
1999 : }
2000 983 : pCntnt = pCntnt->GetNextCntntFrm();
2001 : }
2002 710 : CheckWaitCrsr();
2003 : // OD 14.04.2003 #106346# - consider interrupt formatting.
2004 710 : return !(IsInterrupt() && !mbFormatCntntOnInterrupt);
2005 : }
2006 :
2007 55233 : sal_Bool SwLayAction::IsStopPrt() const
2008 : {
2009 55233 : sal_Bool bResult = sal_False;
2010 :
2011 55233 : if (pImp != NULL && pProgress != NULL)
2012 0 : bResult = pImp->IsStopPrt();
2013 :
2014 55233 : return bResult;
2015 : }
2016 :
2017 : /*************************************************************************
2018 : |*
2019 : |* SwLayAction::FormatSpelling(), _FormatSpelling()
2020 : |*
2021 : |*************************************************************************/
2022 7075 : sal_Bool SwLayIdle::_DoIdleJob( const SwCntntFrm *pCnt, IdleJobType eJob )
2023 : {
2024 : OSL_ENSURE( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" );
2025 : // robust against misuse by e.g. #i52542#
2026 7075 : if( !pCnt->IsTxtFrm() )
2027 0 : return sal_False;
2028 :
2029 7075 : const SwTxtNode* pTxtNode = pCnt->GetNode()->GetTxtNode();
2030 :
2031 7075 : bool bProcess = false;
2032 7075 : switch ( eJob )
2033 : {
2034 : case ONLINE_SPELLING :
2035 2844 : bProcess = pTxtNode->IsWrongDirty(); break;
2036 : case AUTOCOMPLETE_WORDS :
2037 2847 : bProcess = pTxtNode->IsAutoCompleteWordDirty(); break;
2038 : case WORD_COUNT :
2039 1384 : bProcess = pTxtNode->IsWordCountDirty(); break;
2040 : case SMART_TAGS : // SMARTTAGS
2041 0 : bProcess = pTxtNode->IsSmartTagDirty(); break;
2042 : }
2043 :
2044 7075 : if( bProcess )
2045 : {
2046 2572 : ViewShell *pSh = pImp->GetShell();
2047 2572 : if( STRING_LEN == nTxtPos )
2048 : {
2049 1897 : --nTxtPos;
2050 1897 : if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() )
2051 : {
2052 1895 : SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr();
2053 1895 : if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() )
2054 : {
2055 1891 : pCntntNode = pCrsr->GetCntntNode();
2056 1891 : nTxtPos = pCrsr->GetPoint()->nContent.GetIndex();
2057 : }
2058 : }
2059 : }
2060 :
2061 2572 : switch ( eJob )
2062 : {
2063 : case ONLINE_SPELLING :
2064 : {
2065 1725 : SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode, *pSh->GetViewOptions(), nTxtPos ) );
2066 1725 : bPageValid = bPageValid && !pTxtNode->IsWrongDirty();
2067 1725 : if( !bPageValid )
2068 646 : bAllValid = sal_False;
2069 1725 : if ( aRepaint.HasArea() )
2070 54 : pImp->GetShell()->InvalidateWindows( aRepaint );
2071 1725 : if ( Application::AnyInput( VCL_INPUT_MOUSEANDKEYBOARD|VCL_INPUT_OTHER|VCL_INPUT_PAINT ) )
2072 0 : return sal_True;
2073 1725 : break;
2074 : }
2075 : case AUTOCOMPLETE_WORDS :
2076 3 : ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos );
2077 3 : if ( Application::AnyInput( VCL_INPUT_ANY ) )
2078 1 : return sal_True;
2079 2 : break;
2080 : case WORD_COUNT :
2081 : {
2082 844 : const xub_StrLen nEnd = pTxtNode->GetTxt().getLength();
2083 844 : SwDocStat aStat;
2084 844 : pTxtNode->CountWords( aStat, 0, nEnd );
2085 844 : if ( Application::AnyInput( VCL_INPUT_ANY ) )
2086 298 : return sal_True;
2087 546 : break;
2088 : }
2089 : case SMART_TAGS : // SMARTTAGS
2090 : {
2091 0 : const SwRect aRepaint( ((SwTxtFrm*)pCnt)->SmartTagScan( pCntntNode, nTxtPos ) );
2092 0 : bPageValid = bPageValid && !pTxtNode->IsSmartTagDirty();
2093 0 : if( !bPageValid )
2094 0 : bAllValid = sal_False;
2095 0 : if ( aRepaint.HasArea() )
2096 0 : pImp->GetShell()->InvalidateWindows( aRepaint );
2097 0 : if ( Application::AnyInput( VCL_INPUT_MOUSEANDKEYBOARD|VCL_INPUT_OTHER|VCL_INPUT_PAINT ) )
2098 0 : return sal_True;
2099 0 : break;
2100 : }
2101 : }
2102 : }
2103 :
2104 : // The Flys that are anchored to the paragraph need to be considered too.
2105 6776 : if ( pCnt->GetDrawObjs() )
2106 : {
2107 1130 : const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
2108 2825 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2109 : {
2110 1695 : SwAnchoredObject* pObj = rObjs[i];
2111 1695 : if ( pObj->ISA(SwFlyFrm) )
2112 : {
2113 70 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2114 70 : if ( pFly->IsFlyInCntFrm() )
2115 : {
2116 2 : const SwCntntFrm *pC = pFly->ContainsCntnt();
2117 6 : while( pC )
2118 : {
2119 2 : if ( pC->IsTxtFrm() )
2120 : {
2121 2 : if ( _DoIdleJob( pC, eJob ) )
2122 0 : return sal_True;
2123 : }
2124 2 : pC = pC->GetNextCntntFrm();
2125 : }
2126 : }
2127 : }
2128 : }
2129 : }
2130 6776 : return sal_False;
2131 : }
2132 :
2133 6225 : sal_Bool SwLayIdle::DoIdleJob( IdleJobType eJob, sal_Bool bVisAreaOnly )
2134 : {
2135 : // Spellcheck all contents of the pages. Either only the
2136 : // visible ones or all of them.
2137 6225 : const ViewShell* pViewShell = pImp->GetShell();
2138 6225 : const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
2139 6225 : const SwDoc* pDoc = pViewShell->GetDoc();
2140 :
2141 6225 : switch ( eJob )
2142 : {
2143 : case ONLINE_SPELLING :
2144 1739 : if( !pViewOptions->IsOnlineSpell() )
2145 3 : return sal_False;
2146 1736 : break;
2147 : case AUTOCOMPLETE_WORDS :
2148 3478 : if( !pViewOptions->IsAutoCompleteWords() ||
2149 1739 : pDoc->GetAutoCompleteWords().IsLockWordLstLocked())
2150 0 : return sal_False;
2151 1739 : break;
2152 : case WORD_COUNT :
2153 1008 : if ( !pViewShell->getIDocumentStatistics()->GetDocStat().bModified )
2154 0 : return sal_False;
2155 1008 : break;
2156 : case SMART_TAGS :
2157 5217 : if ( pDoc->GetDocShell()->IsHelpDocument() ||
2158 3478 : pDoc->isXForms() ||
2159 1739 : !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
2160 1739 : return sal_False;
2161 0 : break;
2162 : default: OSL_FAIL( "Unknown idle job type" );
2163 : }
2164 :
2165 : SwPageFrm *pPage;
2166 4483 : if ( bVisAreaOnly )
2167 2056 : pPage = pImp->GetFirstVisPage();
2168 : else
2169 2427 : pPage = (SwPageFrm*)pRoot->Lower();
2170 :
2171 4483 : pCntntNode = NULL;
2172 4483 : nTxtPos = STRING_LEN;
2173 :
2174 13233 : while ( pPage )
2175 : {
2176 4598 : bPageValid = sal_True;
2177 4598 : const SwCntntFrm *pCnt = pPage->ContainsCntnt();
2178 15920 : while( pCnt && pPage->IsAnLower( pCnt ) )
2179 : {
2180 7023 : if ( _DoIdleJob( pCnt, eJob ) )
2181 299 : return sal_True;
2182 6724 : pCnt = pCnt->GetNextCntntFrm();
2183 : }
2184 4299 : if ( pPage->GetSortedObjs() )
2185 : {
2186 428 : for ( sal_uInt16 i = 0; pPage->GetSortedObjs() &&
2187 214 : i < pPage->GetSortedObjs()->Count(); ++i )
2188 : {
2189 144 : const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
2190 144 : if ( pObj->ISA(SwFlyFrm) )
2191 : {
2192 95 : const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
2193 95 : const SwCntntFrm *pC = pFly->ContainsCntnt();
2194 285 : while( pC )
2195 : {
2196 95 : if ( pC->IsTxtFrm() )
2197 : {
2198 50 : if ( _DoIdleJob( pC, eJob ) )
2199 0 : return sal_True;
2200 : }
2201 95 : pC = pC->GetNextCntntFrm();
2202 : }
2203 : }
2204 : }
2205 : }
2206 :
2207 4299 : if( bPageValid )
2208 : {
2209 3659 : switch ( eJob )
2210 : {
2211 1138 : case ONLINE_SPELLING : pPage->ValidateSpelling(); break;
2212 1780 : case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break;
2213 741 : case WORD_COUNT : pPage->ValidateWordCount(); break;
2214 0 : case SMART_TAGS : pPage->ValidateSmartTags(); break; // SMARTTAGS
2215 : }
2216 : }
2217 :
2218 4299 : pPage = (SwPageFrm*)pPage->GetNext();
2219 4353 : if ( pPage && bVisAreaOnly &&
2220 54 : !pPage->Frm().IsOver( pImp->GetShell()->VisArea()))
2221 32 : break;
2222 : }
2223 4184 : return sal_False;
2224 : }
2225 :
2226 : #ifdef DBG_UTIL
2227 : /*************************************************************************
2228 : |*
2229 : |* void SwLayIdle::SwLayIdle()
2230 : |*
2231 : |*************************************************************************/
2232 : void SwLayIdle::ShowIdle( ColorData eColorData )
2233 : {
2234 : if ( !m_bIndicator )
2235 : {
2236 : m_bIndicator = true;
2237 : Window *pWin = pImp->GetShell()->GetWin();
2238 : if ( pWin )
2239 : {
2240 : Rectangle aRect( 0, 0, 5, 5 );
2241 : aRect = pWin->PixelToLogic( aRect );
2242 : // OD 2004-04-23 #116347#
2243 : pWin->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
2244 : pWin->SetFillColor( eColorData );
2245 : pWin->SetLineColor();
2246 : pWin->DrawRect( aRect );
2247 : pWin->Pop();
2248 : }
2249 : }
2250 : }
2251 : #define SHOW_IDLE( ColorData ) ShowIdle( ColorData )
2252 : #else
2253 : #define SHOW_IDLE( ColorData )
2254 : #endif // DBG_UTIL
2255 :
2256 : /*************************************************************************
2257 : |*
2258 : |* void SwLayIdle::SwLayIdle()
2259 : |*
2260 : |*************************************************************************/
2261 1029 : SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) :
2262 : pRoot( pRt ),
2263 1029 : pImp( pI )
2264 : #ifdef DBG_UTIL
2265 : , m_bIndicator( false )
2266 : #endif
2267 : {
2268 1029 : pImp->pIdleAct = this;
2269 :
2270 : SHOW_IDLE( COL_LIGHTRED );
2271 :
2272 1029 : pImp->GetShell()->EnableSmooth( sal_False );
2273 :
2274 : // First, spellcheck the visible area. Only if there's nothing
2275 : // to do there, we trigger the IdleFormat.
2276 3087 : if ( !DoIdleJob( SMART_TAGS, sal_True ) &&
2277 2058 : !DoIdleJob( ONLINE_SPELLING, sal_True ) &&
2278 1029 : !DoIdleJob( AUTOCOMPLETE_WORDS, sal_True ) ) // SMARTTAGS
2279 : {
2280 : // Format, then register repaint rectangles with the ViewShell if necessary.
2281 : // This requires running artificial actions, so we don't get undesired
2282 : // effects when for instance the page count gets changed.
2283 : // We remember the shells where the cursor is visible, so we can make
2284 : // it visible again if needed after a document change.
2285 1028 : std::vector<bool> aBools;
2286 1028 : ViewShell *pSh = pImp->GetShell();
2287 1028 : do
2288 1028 : { ++pSh->mnStartAction;
2289 1028 : sal_Bool bVis = sal_False;
2290 1028 : if ( pSh->ISA(SwCrsrShell) )
2291 : {
2292 1028 : bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea());
2293 : }
2294 1028 : aBools.push_back( bVis );
2295 1028 : pSh = (ViewShell*)pSh->GetNext();
2296 1028 : } while ( pSh != pImp->GetShell() );
2297 :
2298 2056 : SwLayAction aAction( pRoot, pImp );
2299 1028 : aAction.SetInputType( VCL_INPUT_ANY );
2300 1028 : aAction.SetIdle( sal_True );
2301 1028 : aAction.SetWaitAllowed( sal_False );
2302 1028 : aAction.Action();
2303 :
2304 : // Further start/end actions only happen if there were paints started
2305 : // somewhere or if the visibility of the CharRects has changed.
2306 1028 : sal_Bool bActions = sal_False;
2307 1028 : sal_uInt16 nBoolIdx = 0;
2308 1028 : do
2309 : {
2310 1028 : --pSh->mnStartAction;
2311 :
2312 1028 : if ( pSh->Imp()->GetRegion() )
2313 8 : bActions = sal_True;
2314 : else
2315 : {
2316 1020 : SwRect aTmp( pSh->VisArea() );
2317 1020 : pSh->UISizeNotify();
2318 :
2319 : // #137134#
2320 : // Are we supposed to crash if pSh isn't a cursor shell?!
2321 : // bActions |= aTmp != pSh->VisArea() ||
2322 : // aBools[nBoolIdx] != ((SwCrsrShell*)pSh)->GetCharRect().IsOver( pSh->VisArea() );
2323 :
2324 : // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!)
2325 : // and the cursor is visible.
2326 1020 : bActions |= aTmp != pSh->VisArea();
2327 1020 : if ( aTmp == pSh->VisArea() && pSh->ISA(SwCrsrShell) )
2328 : {
2329 2040 : bActions |= ((sal_Bool) aBools[nBoolIdx]) !=
2330 1020 : static_cast<SwCrsrShell*>(pSh)->GetCharRect().IsOver( pSh->VisArea() );
2331 : }
2332 : }
2333 :
2334 1028 : pSh = (ViewShell*)pSh->GetNext();
2335 1028 : ++nBoolIdx;
2336 1028 : } while ( pSh != pImp->GetShell() );
2337 :
2338 1028 : if ( bActions )
2339 : {
2340 : // Prepare start/end actions via CrsrShell, so the cursor, selection
2341 : // and VisArea can be set correctly.
2342 8 : nBoolIdx = 0;
2343 8 : do
2344 : {
2345 8 : sal_Bool bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) );
2346 :
2347 8 : if ( bCrsrShell )
2348 8 : ((SwCrsrShell*)pSh)->SttCrsrMove();
2349 : // else
2350 : // pSh->StartAction();
2351 :
2352 : // If there are accrued paints, it's best to simply invalidate
2353 : // the whole window. Otherwise there would arise paint problems whose
2354 : // solution would be disproportionally expensive.
2355 : //fix(18176):
2356 8 : SwViewImp *pViewImp = pSh->Imp();
2357 8 : bool bUnlock = false;
2358 8 : if ( pViewImp->GetRegion() )
2359 : {
2360 8 : pViewImp->DelRegion();
2361 :
2362 : // Cause a repaint with virtual device.
2363 8 : pSh->LockPaint();
2364 8 : bUnlock = true;
2365 : }
2366 :
2367 8 : if ( bCrsrShell )
2368 : // If the Crsr was visible, we need to make it visible again.
2369 : // Otherwise, EndCrsrMove with sal_True for IdleEnd
2370 8 : ((SwCrsrShell*)pSh)->EndCrsrMove( sal_True^aBools[nBoolIdx] );
2371 : // else
2372 : // pSh->EndAction();
2373 8 : if( bUnlock )
2374 : {
2375 8 : if( bCrsrShell )
2376 : {
2377 : // UnlockPaint overwrite the selection from the
2378 : // CrsrShell and calls the virtual method paint
2379 : // to fill the virtual device. This fill dont have
2380 : // paint the selection! -> Set the focus flag at
2381 : // CrsrShell and it dont paint the selection.
2382 8 : ((SwCrsrShell*)pSh)->ShLooseFcs();
2383 8 : pSh->UnlockPaint( sal_True );
2384 8 : ((SwCrsrShell*)pSh)->ShGetFcs( sal_False );
2385 : }
2386 : else
2387 0 : pSh->UnlockPaint( sal_True );
2388 : }
2389 :
2390 8 : pSh = (ViewShell*)pSh->GetNext();
2391 8 : ++nBoolIdx;
2392 :
2393 8 : } while ( pSh != pImp->GetShell() );
2394 : }
2395 :
2396 1028 : if ( !aAction.IsInterrupt() )
2397 : {
2398 1008 : if ( !DoIdleJob( WORD_COUNT, sal_False ) )
2399 710 : if ( !DoIdleJob( SMART_TAGS, sal_False ) )
2400 710 : if ( !DoIdleJob( ONLINE_SPELLING, sal_False ) )
2401 710 : DoIdleJob( AUTOCOMPLETE_WORDS, sal_False ); // SMARTTAGS
2402 : }
2403 :
2404 1028 : bool bInValid = false;
2405 1028 : const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions();
2406 1028 : const ViewShell* pViewShell = pImp->GetShell();
2407 : // See conditions in DoIdleJob()
2408 1028 : const sal_Bool bSpell = rVOpt.IsOnlineSpell();
2409 1028 : const sal_Bool bACmplWrd = rVOpt.IsAutoCompleteWords();
2410 1028 : const sal_Bool bWordCount = pViewShell->getIDocumentStatistics()->GetDocStat().bModified;
2411 2056 : const bool bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() &&
2412 2056 : !pViewShell->GetDoc()->isXForms() &&
2413 2056 : SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
2414 :
2415 1028 : SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
2416 1062 : do
2417 : {
2418 3182 : bInValid = pPg->IsInvalidCntnt() || pPg->IsInvalidLayout() ||
2419 3180 : pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() ||
2420 2120 : pPg->IsInvalidFlyInCnt() ||
2421 1059 : (bSpell && pPg->IsInvalidSpelling()) ||
2422 720 : (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) ||
2423 2402 : (bWordCount && pPg->IsInvalidWordCount()) ||
2424 1062 : (bSmartTags && pPg->IsInvalidSmartTags()); // SMARTTAGS
2425 :
2426 1062 : pPg = (SwPageFrm*)pPg->GetNext();
2427 :
2428 59 : } while ( pPg && !bInValid );
2429 :
2430 1028 : if ( !bInValid )
2431 : {
2432 408 : pRoot->ResetIdleFormat();
2433 408 : SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell();
2434 408 : pDocShell->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) );
2435 1028 : }
2436 : }
2437 :
2438 1029 : pImp->GetShell()->EnableSmooth( sal_True );
2439 :
2440 1029 : if( pImp->IsAccessible() )
2441 5 : pImp->FireAccessibleEvents();
2442 :
2443 : #ifdef DBG_UTIL
2444 : if ( m_bIndicator && pImp->GetShell()->GetWin() )
2445 : {
2446 : // #i75172# Do not invalidate indicator, this may cause a endless loop. Instead, just repaint it
2447 : // This should be replaced by an overlay object in the future, anyways. Since it's only for debug
2448 : // purposes, it is not urgent.
2449 : m_bIndicator = false; SHOW_IDLE( COL_LIGHTGREEN );
2450 : }
2451 : #endif
2452 1029 : }
2453 :
2454 1029 : SwLayIdle::~SwLayIdle()
2455 : {
2456 1029 : pImp->pIdleAct = 0;
2457 1128 : }
2458 :
2459 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|