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