1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include "rootfrm.hxx"
23 #include "pagefrm.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"
33 #include "dflyobj.hxx"
35 #include "frmtool.hxx"
36 #include "dcontact.hxx"
37 #include "ndtxt.hxx" // OnlineSpelling
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"
47 #include <sfx2/event.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>
59 #include <fmtsrnd.hxx>
60 #include <fmtanchr.hxx>
61 #include <tools/shl.hxx>
62 #include <sfx2/progress.hxx>
65 #include "swmodule.hxx"
66 #include "fmtline.hxx"
70 #include "notxtfrm.hxx"
71 #include "flyfrms.hxx"
73 #include "fmtornt.hxx"
74 #include "sectfrm.hxx"
75 #include "lineinfo.hxx"
76 #include <acmplwrd.hxx>
78 #include <sortedobjs.hxx>
79 #include <objectformatter.hxx>
80 #include <PostItMgr.hxx>
83 /*************************************************************************
85 |* SwLayAction static stuff
87 |*************************************************************************/
89 #define IS_FLYS (pPage->GetSortedObjs())
90 #define IS_INVAFLY (pPage->IsInvalidFly())
93 // Save some typing work to avoid accessing destroyed pages.
94 #if OSL_DEBUG_LEVEL > 1
96 static void BreakPoint()
105 pLayoutAccess->GetLayouter()->EndLoopControl(); \
114 pLayoutAccess->GetLayouter()->EndLoopControl(); \
122 if ( IsReschedule() ) \
124 if (pProgress) pProgress->Reschedule(); \
125 ::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \
129 inline sal_uLong
Ticks()
131 return 1000 * clock() / CLOCKS_PER_SEC
;
134 void SwLayAction::CheckWaitCrsr()
137 if ( !IsWait() && IsWaitAllowed() && IsPaint() &&
138 ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC
/2) )
140 pWait
= new SwWait( *pRoot
->GetFmt()->GetDoc()->GetDocShell(), sal_True
);
144 /*************************************************************************
146 |* SwLayAction::CheckIdleEnd()
148 |*************************************************************************/
149 // Time over already?
150 inline void SwLayAction::CheckIdleEnd()
153 bInput
= GetInputType() && Application::AnyInput( GetInputType() );
156 /*************************************************************************
158 |* SwLayAction::SetStatBar()
160 |*************************************************************************/
161 void SwLayAction::SetStatBar( sal_Bool bNew
)
165 nEndPage
= pRoot
->GetPageNum();
166 nEndPage
+= nEndPage
* 10 / 100;
169 nEndPage
= USHRT_MAX
;
172 /*************************************************************************
174 |* SwLayAction::PaintCntnt()
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
181 |*************************************************************************/
182 sal_Bool
SwLayAction::PaintWithoutFlys( const SwRect
&rRect
, const SwCntntFrm
*pCnt
,
183 const SwPageFrm
*pPage
)
185 SwRegionRects
aTmp( rRect
);
186 const SwSortedObjs
&rObjs
= *pPage
->GetSortedObjs();
187 const SwFlyFrm
*pSelfFly
= pCnt
->FindFlyFrm();
190 for ( i
= 0; i
< rObjs
.Count() && !aTmp
.empty(); ++i
)
192 SdrObject
*pO
= rObjs
[i
]->DrawObj();
193 if ( !pO
->ISA(SwVirtFlyDrawObj
) )
196 // OD 2004-01-15 #110582# - do not consider invisible objects
197 const IDocumentDrawModelAccess
* pIDDMA
= pPage
->GetFmt()->getIDocumentDrawModelAccess();
198 if ( !pIDDMA
->IsVisibleLayerId( pO
->GetLayer() ) )
203 SwFlyFrm
*pFly
= ((SwVirtFlyDrawObj
*)pO
)->GetFlyFrm();
205 if ( pFly
== pSelfFly
|| !rRect
.IsOver( pFly
->Frm() ) )
208 if ( pSelfFly
&& pSelfFly
->IsLowerOf( pFly
) )
211 if ( pFly
->GetVirtDrawObj()->GetLayer() == pIDDMA
->GetHellId() )
216 const SdrObject
*pTmp
= pSelfFly
->GetVirtDrawObj();
217 if ( pO
->GetLayer() == pTmp
->GetLayer() )
219 if ( pO
->GetOrdNumDirect() < pTmp
->GetOrdNumDirect() )
220 // Only look at things above us, if inside the same layer
225 const sal_Bool bLowerOfSelf
= pFly
->IsLowerOf( pSelfFly
);
226 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
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 if ( pFly
->Lower() &&
238 pFly
->Lower()->IsNoTxtFrm() &&
239 ( ((SwNoTxtFrm
*)pFly
->Lower())->IsTransparent() ||
240 pFly
->GetFmt()->GetSurround().IsContour() )
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 if ( pFly
->IsBackgroundTransparent() ||
250 pFly
->IsShadowTransparent() )
258 sal_Bool bRetPaint
= sal_False
;
259 for ( SwRects::const_iterator it
= aTmp
.begin(); it
!= aTmp
.end(); ++it
)
260 bRetPaint
|= pImp
->GetShell()->AddPaintRect( *it
);
264 inline sal_Bool
SwLayAction::_PaintCntnt( const SwCntntFrm
*pCntnt
,
265 const SwPageFrm
*pPage
,
266 const SwRect
&rRect
)
268 if ( rRect
.HasArea() )
270 if ( pPage
->GetSortedObjs() )
271 return PaintWithoutFlys( rRect
, pCntnt
, pPage
);
273 return pImp
->GetShell()->AddPaintRect( rRect
);
278 void SwLayAction::PaintCntnt( const SwCntntFrm
*pCnt
,
279 const SwPageFrm
*pPage
,
280 const SwRect
&rOldRect
,
285 if ( pCnt
->IsCompletePaint() || !pCnt
->IsTxtFrm() )
287 SwRect
aPaint( pCnt
->PaintArea() );
288 if ( !_PaintCntnt( pCnt
, pPage
, aPaint
) )
289 pCnt
->ResetCompletePaint();
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 long nOldHeight
= (rOldRect
.*fnRect
->fnGetHeight
)();
296 long nNewHeight
= (pCnt
->Frm().*fnRect
->fnGetHeight
)();
297 const bool bHeightDiff
= nOldHeight
!= nNewHeight
;
300 // OD 05.11.2002 #94454# - consider whole potential paint area.
301 //SwRect aDrawRect( pCnt->UnionFrm( sal_True ) );
302 SwRect
aDrawRect( pCnt
->PaintArea() );
303 if( nOldHeight
> nNewHeight
)
304 nOldBottom
= (pCnt
->*fnRect
->fnGetPrtBottom
)();
305 (aDrawRect
.*fnRect
->fnSetTop
)( nOldBottom
);
306 _PaintCntnt( pCnt
, pPage
, aDrawRect
);
308 // paint content area
309 SwRect aPaintRect
= static_cast<SwTxtFrm
*>(const_cast<SwCntntFrm
*>(pCnt
))->Paint();
310 _PaintCntnt( pCnt
, pPage
, aPaintRect
);
313 if ( pCnt
->IsRetouche() && !pCnt
->GetNext() )
315 const SwFrm
*pTmp
= pCnt
;
316 if( pCnt
->IsInSct() )
318 const SwSectionFrm
* pSct
= pCnt
->FindSctFrm();
319 if( pSct
->IsRetouche() && !pSct
->GetNext() )
322 SwRect
aRect( pTmp
->GetUpper()->PaintArea() );
323 (aRect
.*fnRect
->fnSetTop
)( (pTmp
->*fnRect
->fnGetPrtBottom
)() );
324 if ( !_PaintCntnt( pCnt
, pPage
, aRect
) )
325 pCnt
->ResetRetouche();
329 /*************************************************************************
331 |* SwLayAction::SwLayAction()
333 |*************************************************************************/
334 SwLayAction::SwLayAction( SwRootFrm
*pRt
, SwViewImp
*pI
) :
340 nPreInvaPage( USHRT_MAX
),
341 nStartTicks( Ticks() ),
343 nEndPage( USHRT_MAX
),
344 nCheckPageNum( USHRT_MAX
)
346 bPaintExtraData
= ::IsExtraData( pImp
->GetShell()->GetDoc() );
347 bPaint
= bComplete
= bWaitAllowed
= bCheckPages
= sal_True
;
348 bInput
= bAgain
= bNextCycle
= bCalcLayout
= bIdle
= bReschedule
=
349 bUpdateExpFlds
= bBrowseActionStop
= bActionInProgress
= sal_False
;
350 // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>.
351 mbFormatCntntOnInterrupt
= sal_False
;
353 pImp
->pLayAct
= this; // register there
356 SwLayAction::~SwLayAction()
358 OSL_ENSURE( !pWait
, "Wait object not destroyed" );
359 pImp
->pLayAct
= 0; // unregister
362 /*************************************************************************
364 |* SwLayAction::Reset()
366 |*************************************************************************/
367 void SwLayAction::Reset()
370 nStartTicks
= Ticks();
372 nEndPage
= nPreInvaPage
= nCheckPageNum
= USHRT_MAX
;
373 bPaint
= bComplete
= bWaitAllowed
= bCheckPages
= sal_True
;
374 bInput
= bAgain
= bNextCycle
= bCalcLayout
= bIdle
= bReschedule
=
375 bUpdateExpFlds
= bBrowseActionStop
= sal_False
;
378 /*************************************************************************
380 |* SwLayAction::RemoveEmptyBrowserPages()
382 |*************************************************************************/
384 sal_Bool
SwLayAction::RemoveEmptyBrowserPages()
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 sal_Bool bRet
= sal_False
;
389 const ViewShell
*pSh
= pRoot
->GetCurrShell();
390 if( pSh
&& pSh
->GetViewOptions()->getBrowseMode() )
392 SwPageFrm
*pPage
= (SwPageFrm
*)pRoot
->Lower();
395 if ( (pPage
->GetSortedObjs() && pPage
->GetSortedObjs()->Count()) ||
396 pPage
->ContainsCntnt() )
397 pPage
= (SwPageFrm
*)pPage
->GetNext();
401 SwPageFrm
*pDel
= pPage
;
402 pPage
= (SwPageFrm
*)pPage
->GetNext();
412 /*************************************************************************
414 |* SwLayAction::Action()
416 |*************************************************************************/
417 void SwLayAction::Action()
419 bActionInProgress
= sal_True
;
421 //TurboMode? Hands-off during idle-format
422 if ( IsPaint() && !IsIdle() && TurboAction() )
424 delete pWait
, pWait
= 0;
425 pRoot
->ResetTurboFlag();
426 bActionInProgress
= sal_False
;
427 pRoot
->DeleteEmptySct();
430 else if ( pRoot
->GetTurbo() )
432 pRoot
->DisallowTurbo();
433 const SwFrm
*pFrm
= pRoot
->GetTurbo();
435 pFrm
->InvalidatePage();
437 pRoot
->DisallowTurbo();
439 if ( IsCalcLayout() )
440 SetCheckPages( sal_False
);
443 bAgain
|= RemoveEmptyBrowserPages();
446 bAgain
= bNextCycle
= sal_False
;
448 bAgain
|= RemoveEmptyBrowserPages();
450 pRoot
->DeleteEmptySct();
452 delete pWait
, pWait
= 0;
454 //Turbo-Action permitted again for all cases.
455 pRoot
->ResetTurboFlag();
458 SetCheckPages( sal_True
);
460 bActionInProgress
= sal_False
;
463 SwPageFrm
* SwLayAction::CheckFirstVisPage( SwPageFrm
*pPage
)
465 SwCntntFrm
*pCnt
= pPage
->FindFirstBodyCntnt();
466 SwCntntFrm
*pChk
= pCnt
;
467 sal_Bool bPageChgd
= sal_False
;
468 while ( pCnt
&& pCnt
->IsFollow() )
469 pCnt
= static_cast<SwCntntFrm
*>(pCnt
)->FindMaster();
470 if ( pCnt
&& pChk
!= pCnt
)
471 { bPageChgd
= sal_True
;
472 pPage
= pCnt
->FindPageFrm();
475 if ( !pPage
->GetFmt()->GetDoc()->GetFtnIdxs().empty() )
477 SwFtnContFrm
*pCont
= pPage
->FindFtnCont();
480 pCnt
= pCont
->ContainsCntnt();
482 while ( pCnt
&& pCnt
->IsFollow() )
483 pCnt
= (SwCntntFrm
*)pCnt
->FindPrev();
484 if ( pCnt
&& pCnt
!= pChk
)
488 // Use the 'topmost' page
489 SwPageFrm
*pTmp
= pCnt
->FindPageFrm();
490 if ( pPage
->GetPhyPageNum() > pTmp
->GetPhyPageNum() )
494 pPage
= pCnt
->FindPageFrm();
501 // #114798# - unlock position on start and end of page
503 static void unlockPositionOfObjects( SwPageFrm
*pPageFrm
)
507 SwSortedObjs
* pObjs
= pPageFrm
->GetSortedObjs();
511 for ( ; i
< pObjs
->Count(); ++i
)
513 SwAnchoredObject
* pObj
= (*pObjs
)[i
];
514 pObj
->UnlockPosition();
519 void SwLayAction::InternalAction()
521 OSL_ENSURE( pRoot
->Lower()->IsPageFrm(), ":-( No page below the root.");
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 SwPageFrm
*pPage
= IsComplete() ? (SwPageFrm
*)pRoot
->Lower() :
531 pImp
->GetFirstVisPage();
533 pPage
= (SwPageFrm
*)pRoot
->Lower();
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.
538 pPage
= CheckFirstVisPage( pPage
);
539 sal_uInt16 nFirstPageNum
= pPage
->GetPhyPageNum();
541 while ( pPage
&& !pPage
->IsInvalid() && !pPage
->IsInvalidFly() )
542 pPage
= (SwPageFrm
*)pPage
->GetNext();
544 IDocumentLayoutAccess
*pLayoutAccess
= pRoot
->GetFmt()->getIDocumentLayoutAccess();
545 sal_Bool bNoLoop
= pPage
? SwLayouter::StartLoopControl( pRoot
->GetFmt()->GetDoc(), pPage
) : sal_False
;
546 sal_uInt16 nPercentPageNum
= 0;
547 while ( (pPage
&& !IsInterrupt()) || nCheckPageNum
!= USHRT_MAX
)
549 if ( !pPage
&& nCheckPageNum
!= USHRT_MAX
&&
550 (!pPage
|| pPage
->GetPhyPageNum() >= nCheckPageNum
) )
552 if ( !pPage
|| pPage
->GetPhyPageNum() > nCheckPageNum
)
554 SwPageFrm
*pPg
= (SwPageFrm
*)pRoot
->Lower();
555 while ( pPg
&& pPg
->GetPhyPageNum() < nCheckPageNum
)
556 pPg
= (SwPageFrm
*)pPg
->GetNext();
562 SwPageFrm
*pTmp
= pPage
->GetPrev() ?
563 (SwPageFrm
*)pPage
->GetPrev() : pPage
;
564 SetCheckPages( sal_True
);
565 SwFrm::CheckPageDescs( pPage
);
566 SetCheckPages( sal_False
);
567 nCheckPageNum
= USHRT_MAX
;
572 if ( nEndPage
!= USHRT_MAX
&& pPage
->GetPhyPageNum() > nPercentPageNum
)
574 nPercentPageNum
= pPage
->GetPhyPageNum();
575 ::SetProgressState( nPercentPageNum
, pImp
->GetShell()->GetDoc()->GetDocShell());
578 // No Shortcut for Idle or CalcLayout
579 if ( !IsIdle() && !IsComplete() && IsShortCut( pPage
) )
581 pRoot
->DeleteEmptySct();
583 if ( !IsInterrupt() &&
584 (pRoot
->IsSuperfluous() || pRoot
->IsAssertFlyPages()) )
586 if ( pRoot
->IsAssertFlyPages() )
587 pRoot
->AssertFlyPages();
588 if ( pRoot
->IsSuperfluous() )
590 sal_Bool bOld
= IsAgain();
591 pRoot
->RemoveSuperfluous();
597 pLayoutAccess
->GetLayouter()->EndLoopControl();
600 pPage
= (SwPageFrm
*)pRoot
->Lower();
601 while ( pPage
&& !pPage
->IsInvalid() && !pPage
->IsInvalidFly() )
602 pPage
= (SwPageFrm
*)pPage
->GetNext();
603 while ( pPage
&& pPage
->GetNext() &&
604 pPage
->GetPhyPageNum() < nFirstPageNum
)
605 pPage
= (SwPageFrm
*)pPage
->GetNext();
612 pRoot
->DeleteEmptySct();
615 while ( !IsInterrupt() && !IsNextCycle() &&
616 ((IS_FLYS
&& IS_INVAFLY
) || pPage
->IsInvalid()) )
618 unlockPositionOfObjects( pPage
);
621 SwObjectFormatter::FormatObjsAtFrm( *pPage
, *pPage
, this );
624 // If there are no (more) Flys, the flags are superfluous.
625 pPage
->ValidateFlyLayout();
626 pPage
->ValidateFlyCntnt();
628 // #i28701# - change condition
629 while ( !IsInterrupt() && !IsNextCycle() &&
630 ( pPage
->IsInvalid() ||
631 (IS_FLYS
&& IS_INVAFLY
) ) )
633 PROTOCOL( pPage
, PROT_FILE_INIT
, 0, 0)
636 // #i81146# new loop control
637 sal_uInt16 nLoopControlRuns_1
= 0;
638 const sal_uInt16 nLoopControlMax
= 20;
640 while ( !IsNextCycle() && pPage
->IsInvalidLayout() )
642 pPage
->ValidateLayout();
644 if ( ++nLoopControlRuns_1
> nLoopControlMax
)
646 OSL_FAIL( "LoopControl_1 in SwLayAction::InternalAction" );
650 FormatLayout( pPage
);
653 // #i28701# - change condition
654 if ( !IsNextCycle() &&
655 ( pPage
->IsInvalidCntnt() ||
656 (IS_FLYS
&& IS_INVAFLY
) ) )
658 pPage
->ValidateFlyInCnt();
659 pPage
->ValidateCntnt();
661 pPage
->ValidateFlyLayout();
662 pPage
->ValidateFlyCntnt();
663 if ( !FormatCntnt( pPage
) )
666 pPage
->InvalidateCntnt();
667 pPage
->InvalidateFlyInCnt();
669 pPage
->InvalidateFlyLayout();
670 pPage
->InvalidateFlyCntnt();
671 if ( IsBrowseActionStop() )
676 pLayoutAccess
->GetLayouter()->LoopControl( pPage
, LOOP_PAGE
);
679 unlockPositionOfObjects( pPage
);
682 // A previous page may be invalid again.
686 // If there are no (more) Flys, the flags are superfluous.
687 pPage
->ValidateFlyLayout();
688 pPage
->ValidateFlyCntnt();
690 if ( !IsInterrupt() )
692 SetNextCycle( sal_False
);
694 if ( nPreInvaPage
!= USHRT_MAX
)
696 if( !IsComplete() && nPreInvaPage
+ 2 < nFirstPageNum
)
698 pImp
->SetFirstVisPageInvalid();
699 SwPageFrm
*pTmpPage
= pImp
->GetFirstVisPage();
700 nFirstPageNum
= pTmpPage
->GetPhyPageNum();
701 if( nPreInvaPage
< nFirstPageNum
)
703 nPreInvaPage
= nFirstPageNum
;
707 while ( pPage
->GetPrev() && pPage
->GetPhyPageNum() > nPreInvaPage
)
708 pPage
= (SwPageFrm
*)pPage
->GetPrev();
709 nPreInvaPage
= USHRT_MAX
;
712 while ( pPage
->GetPrev() &&
713 ( ((SwPageFrm
*)pPage
->GetPrev())->IsInvalid() ||
714 ( ((SwPageFrm
*)pPage
->GetPrev())->GetSortedObjs() &&
715 ((SwPageFrm
*)pPage
->GetPrev())->IsInvalidFly())) &&
716 (((SwPageFrm
*)pPage
->GetPrev())->GetPhyPageNum() >=
719 pPage
= (SwPageFrm
*)pPage
->GetPrev();
722 // Continue to the next invalid page
723 while ( pPage
&& !pPage
->IsInvalid() &&
724 (!IS_FLYS
|| !IS_INVAFLY
) )
726 pPage
= (SwPageFrm
*)pPage
->GetNext();
729 pLayoutAccess
->GetLayouter()->LoopControl( pPage
, LOOP_PAGE
);
733 if ( !pPage
&& !IsInterrupt() &&
734 (pRoot
->IsSuperfluous() || pRoot
->IsAssertFlyPages()) )
736 if ( pRoot
->IsAssertFlyPages() )
737 pRoot
->AssertFlyPages();
738 if ( pRoot
->IsSuperfluous() )
740 sal_Bool bOld
= IsAgain();
741 pRoot
->RemoveSuperfluous();
747 pLayoutAccess
->GetLayouter()->EndLoopControl();
750 pPage
= (SwPageFrm
*)pRoot
->Lower();
751 while ( pPage
&& !pPage
->IsInvalid() && !pPage
->IsInvalidFly() )
752 pPage
= (SwPageFrm
*)pPage
->GetNext();
753 while ( pPage
&& pPage
->GetNext() &&
754 pPage
->GetPhyPageNum() < nFirstPageNum
)
755 pPage
= (SwPageFrm
*)pPage
->GetNext();
758 if ( IsInterrupt() && pPage
)
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
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
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 SwPageFrm
*pPg
= pPage
;
778 const SwRect
&rVis
= pImp
->GetShell()->VisArea();
780 while( pPg
&& pPg
->Frm().Bottom() < rVis
.Top() )
781 pPg
= (SwPageFrm
*)pPg
->GetNext();
783 pPg
= pPg
? (SwPageFrm
*)pPg
->GetPrev() : pPage
;
785 // set flag for interrupt content formatting
786 mbFormatCntntOnInterrupt
= IsInput() && !IsStopPrt();
787 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 while ( pPg
&& ( pPg
->Frm().Top() < nBottom
||
792 ( IsIdle() && pPg
== pPage
) ) )
794 unlockPositionOfObjects( pPg
);
798 // #i81146# new loop control
799 sal_uInt16 nLoopControlRuns_2
= 0;
800 const sal_uInt16 nLoopControlMax
= 20;
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 while ( ( mbFormatCntntOnInterrupt
&&
807 ( pPg
->IsInvalid() ||
808 ( pPg
->GetSortedObjs() && pPg
->IsInvalidFly() ) ) ) ||
809 ( !mbFormatCntntOnInterrupt
&& pPg
->IsInvalidLayout() ) )
812 // #i50432# - format also at-page anchored objects
813 SwObjectFormatter::FormatObjsAtFrm( *pPg
, *pPg
, this );
814 if ( !pPg
->GetSortedObjs() )
816 pPg
->ValidateFlyLayout();
817 pPg
->ValidateFlyCntnt();
820 // #i81146# new loop control
821 sal_uInt16 nLoopControlRuns_3
= 0;
823 while ( pPg
->IsInvalidLayout() )
825 pPg
->ValidateLayout();
827 if ( ++nLoopControlRuns_3
> nLoopControlMax
)
829 OSL_FAIL( "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" );
838 if ( mbFormatCntntOnInterrupt
&&
839 ( pPg
->IsInvalidCntnt() ||
840 ( pPg
->GetSortedObjs() && pPg
->IsInvalidFly() ) ) )
842 pPg
->ValidateFlyInCnt();
843 pPg
->ValidateCntnt();
845 pPg
->ValidateFlyLayout();
846 pPg
->ValidateFlyCntnt();
848 if ( ++nLoopControlRuns_2
> nLoopControlMax
)
850 OSL_FAIL( "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" );
854 if ( !FormatCntnt( pPg
) )
857 pPg
->InvalidateCntnt();
858 pPg
->InvalidateFlyInCnt();
860 pPg
->InvalidateFlyLayout();
861 pPg
->InvalidateFlyCntnt();
863 // #i46807# - we are statisfied, if the content is formatted once complete.
871 unlockPositionOfObjects( pPg
);
872 pPg
= (SwPageFrm
*)pPg
->GetNext();
874 // reset flag for special interrupt content formatting.
875 mbFormatCntntOnInterrupt
= sal_False
;
879 pLayoutAccess
->GetLayouter()->EndLoopControl();
881 /*************************************************************************
883 |* SwLayAction::TurboAction(), _TurboAction()
885 |*************************************************************************/
886 sal_Bool
SwLayAction::_TurboAction( const SwCntntFrm
*pCnt
)
889 const SwPageFrm
*pPage
= 0;
890 if ( !pCnt
->IsValid() || pCnt
->IsCompletePaint() || pCnt
->IsRetouche() )
892 const SwRect
aOldRect( pCnt
->UnionFrm( sal_True
) );
893 const long nOldBottom
= pCnt
->Frm().Top() + pCnt
->Prt().Bottom();
895 if ( pCnt
->Frm().Bottom() < aOldRect
.Bottom() )
898 pPage
= pCnt
->FindPageFrm();
899 PaintCntnt( pCnt
, pPage
, aOldRect
, nOldBottom
);
901 if ( !pCnt
->GetValidLineNumFlag() && pCnt
->IsTxtFrm() )
903 const sal_uLong nAllLines
= ((SwTxtFrm
*)pCnt
)->GetAllLines();
904 ((SwTxtFrm
*)pCnt
)->RecalcAllLines();
905 if ( nAllLines
!= ((SwTxtFrm
*)pCnt
)->GetAllLines() )
907 if ( IsPaintExtraData() )
908 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 const SwCntntFrm
*pNxt
= pCnt
->GetNextCntntFrm();
915 (pNxt
->IsInTab() || pNxt
->IsInDocBody() != pCnt
->IsInDocBody()) )
916 pNxt
= pNxt
->GetNextCntntFrm();
918 pNxt
->InvalidatePage();
923 if ( pPage
->IsInvalidLayout() || (IS_FLYS
&& IS_INVAFLY
) )
927 pPage
= pCnt
->FindPageFrm();
929 // OD 2004-05-10 #i28701# - format floating screen objects at content frame.
930 if ( pCnt
->IsTxtFrm() &&
931 !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm
*>(pCnt
)),
937 if ( pPage
->IsInvalidCntnt() )
942 sal_Bool
SwLayAction::TurboAction()
944 sal_Bool bRet
= sal_True
;
946 if ( pRoot
->GetTurbo() )
948 if ( !_TurboAction( pRoot
->GetTurbo() ) )
959 /*************************************************************************
961 |* SwLayAction::IsShortCut()
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.
971 |*************************************************************************/
972 static bool lcl_IsInvaLay( const SwFrm
*pFrm
, long nBottom
)
976 (pFrm
->IsCompletePaint() && ( pFrm
->Frm().Top() < nBottom
) )
984 static const SwFrm
*lcl_FindFirstInvaLay( const SwFrm
*pFrm
, long nBottom
)
986 OSL_ENSURE( pFrm
->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" );
988 if (lcl_IsInvaLay(pFrm
, nBottom
))
990 pFrm
= ((SwLayoutFrm
*)pFrm
)->Lower();
993 if ( pFrm
->IsLayoutFrm() )
995 if (lcl_IsInvaLay(pFrm
, nBottom
))
998 if ( 0 != (pTmp
= lcl_FindFirstInvaLay( pFrm
, nBottom
)) )
1001 pFrm
= pFrm
->GetNext();
1006 static const SwFrm
*lcl_FindFirstInvaCntnt( const SwLayoutFrm
*pLay
, long nBottom
,
1007 const SwCntntFrm
*pFirst
)
1009 const SwCntntFrm
*pCnt
= pFirst
? pFirst
->GetNextCntntFrm() :
1010 pLay
->ContainsCntnt();
1013 if ( !pCnt
->IsValid() || pCnt
->IsCompletePaint() )
1015 if ( pCnt
->Frm().Top() <= nBottom
)
1019 if ( pCnt
->GetDrawObjs() )
1021 const SwSortedObjs
&rObjs
= *pCnt
->GetDrawObjs();
1022 for ( sal_uInt16 i
= 0; i
< rObjs
.Count(); ++i
)
1024 const SwAnchoredObject
* pObj
= rObjs
[i
];
1025 if ( pObj
->ISA(SwFlyFrm
) )
1027 const SwFlyFrm
* pFly
= static_cast<const SwFlyFrm
*>(pObj
);
1028 if ( pFly
->IsFlyInCntFrm() )
1030 if ( ((SwFlyInCntFrm
*)pFly
)->IsInvalid() ||
1031 pFly
->IsCompletePaint() )
1033 if ( pFly
->Frm().Top() <= nBottom
)
1036 const SwFrm
*pFrm
= lcl_FindFirstInvaCntnt( pFly
, nBottom
, 0 );
1037 if ( pFrm
&& pFrm
->Frm().Bottom() <= nBottom
)
1043 if ( pCnt
->Frm().Top() > nBottom
&& !pCnt
->IsInTab() )
1045 pCnt
= pCnt
->GetNextCntntFrm();
1046 if ( !pLay
->IsAnLower( pCnt
) )
1052 // #i37877# - consider drawing objects
1053 static const SwAnchoredObject
* lcl_FindFirstInvaObj( const SwPageFrm
* _pPage
,
1056 OSL_ENSURE( _pPage
->GetSortedObjs(), "FindFirstInvaObj, no Objs" );
1058 for ( sal_uInt16 i
= 0; i
< _pPage
->GetSortedObjs()->Count(); ++i
)
1060 const SwAnchoredObject
* pObj
= (*_pPage
->GetSortedObjs())[i
];
1061 if ( pObj
->ISA(SwFlyFrm
) )
1063 const SwFlyFrm
* pFly
= static_cast<const SwFlyFrm
*>(pObj
);
1064 if ( pFly
->Frm().Top() <= _nBottom
)
1066 if ( pFly
->IsInvalid() || pFly
->IsCompletePaint() )
1070 if ( 0 != (pTmp
= lcl_FindFirstInvaCntnt( pFly
, _nBottom
, 0 )) &&
1071 pTmp
->Frm().Top() <= _nBottom
)
1075 else if ( pObj
->ISA(SwAnchoredDrawObject
) )
1077 if ( !static_cast<const SwAnchoredDrawObject
*>(pObj
)->IsValidPos() )
1086 sal_Bool
SwLayAction::IsShortCut( SwPageFrm
*&prPage
)
1088 sal_Bool bRet
= sal_False
;
1089 const ViewShell
*pSh
= pRoot
->GetCurrShell();
1090 const bool bBrowse
= pSh
&& pSh
->GetViewOptions()->getBrowseMode();
1092 // If the page is not valid, we quickly format it, otherwise
1093 // there's gonna be no end of trouble
1094 if ( !prPage
->IsValid() )
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.
1104 SwFrm
* pPageLowerFrm
= prPage
->Lower();
1105 while ( pPageLowerFrm
)
1107 pPageLowerFrm
->Calc();
1108 pPageLowerFrm
= pPageLowerFrm
->GetNext();
1112 FormatLayout( prPage
);
1118 const SwRect
&rVis
= pImp
->GetShell()->VisArea();
1119 if ( (prPage
->Frm().Top() >= rVis
.Bottom()) ||
1120 (prPage
->Frm().Left()>= rVis
.Right()) )
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).
1132 // This is irrelevant for the browser, if the last Cnt above it
1133 // isn't visible anymore.
1135 const SwPageFrm
*p2ndPage
= prPage
;
1136 const SwCntntFrm
*pCntnt
;
1137 const SwLayoutFrm
* pBody
= p2ndPage
->FindBodyCont();
1138 if( p2ndPage
->IsFtnPage() && pBody
)
1139 pBody
= (SwLayoutFrm
*)pBody
->GetNext();
1140 pCntnt
= pBody
? pBody
->ContainsCntnt() : 0;
1141 while ( p2ndPage
&& !pCntnt
)
1143 p2ndPage
= (SwPageFrm
*)p2ndPage
->GetNext();
1146 pBody
= p2ndPage
->FindBodyCont();
1147 if( p2ndPage
->IsFtnPage() && pBody
)
1148 pBody
= (SwLayoutFrm
*)pBody
->GetNext();
1149 pCntnt
= pBody
? pBody
->ContainsCntnt() : 0;
1154 bool bTstCnt
= true;
1157 // Is the Cnt before already invisible?
1158 const SwFrm
*pLst
= pCntnt
;
1159 if ( pLst
->IsInTab() )
1160 pLst
= pCntnt
->FindTabFrm();
1161 if ( pLst
->IsInSct() )
1162 pLst
= pCntnt
->FindSctFrm();
1163 pLst
= pLst
->FindPrev();
1165 (pLst
->Frm().Top() >= rVis
.Bottom() ||
1166 pLst
->Frm().Left()>= rVis
.Right()) )
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 bool bPageChg
= false;
1179 if ( pCntnt
->IsInSct() )
1181 const SwSectionFrm
*pSct
= ((SwFrm
*)pCntnt
)->ImplFindSctFrm();
1182 if ( !pSct
->IsValid() )
1185 pSct
->SetCompletePaint();
1189 bPageChg
= pCntnt
->FindPageFrm() != p2ndPage
&&
1194 if ( !bPageChg
&& !pCntnt
->IsValid() )
1197 pCntnt
->SetCompletePaint();
1201 bPageChg
= pCntnt
->FindPageFrm() != p2ndPage
&&
1205 if ( !bPageChg
&& pCntnt
->IsInTab() )
1207 const SwTabFrm
*pTab
= ((SwFrm
*)pCntnt
)->ImplFindTabFrm();
1208 if ( !pTab
->IsValid() )
1211 pTab
->SetCompletePaint();
1215 bPageChg
= pCntnt
->FindPageFrm() != p2ndPage
&&
1220 if ( !bPageChg
&& pCntnt
->IsInSct() )
1222 const SwSectionFrm
*pSct
= ((SwFrm
*)pCntnt
)->ImplFindSctFrm();
1223 if ( !pSct
->IsValid() )
1226 pSct
->SetCompletePaint();
1230 bPageChg
= pCntnt
->FindPageFrm() != p2ndPage
&&
1239 const SwPageFrm
* pTmp
= pCntnt
->FindPageFrm();
1240 if ( pTmp
->GetPhyPageNum() < prPage
->GetPhyPageNum() &&
1243 prPage
= (SwPageFrm
*)pTmp
;
1247 prPage
= (SwPageFrm
*)prPage
->GetPrev();
1250 // #121980# - no shortcut, if at previous page
1251 // an anchored object is registered, whose anchor is <pCntnt>.
1252 else if ( prPage
->GetPrev() &&
1253 static_cast<SwPageFrm
*>(prPage
->GetPrev())->GetSortedObjs() )
1255 SwSortedObjs
* pObjs
=
1256 static_cast<SwPageFrm
*>(prPage
->GetPrev())->GetSortedObjs();
1260 for ( ; i
< pObjs
->Count(); ++i
)
1262 SwAnchoredObject
* pObj
= (*pObjs
)[i
];
1263 if ( pObj
->GetAnchorFrmContainingAnchPos() == pCntnt
)
1275 if ( !bRet
&& bBrowse
)
1277 const long nBottom
= rVis
.Bottom();
1278 const SwAnchoredObject
* pObj( 0L );
1279 if ( prPage
->GetSortedObjs() &&
1280 (prPage
->IsInvalidFlyLayout() || prPage
->IsInvalidFlyCntnt()) &&
1281 0 != (pObj
= lcl_FindFirstInvaObj( prPage
, nBottom
)) &&
1282 pObj
->GetObjRect().Top() <= nBottom
)
1286 const SwFrm
* pFrm( 0L );
1287 if ( prPage
->IsInvalidLayout() &&
1288 0 != (pFrm
= lcl_FindFirstInvaLay( prPage
, nBottom
)) &&
1289 pFrm
->Frm().Top() <= nBottom
)
1293 if ( (prPage
->IsInvalidCntnt() || prPage
->IsInvalidFlyInCnt()) &&
1294 0 != (pFrm
= lcl_FindFirstInvaCntnt( prPage
, nBottom
, 0 )) &&
1295 pFrm
->Frm().Top() <= nBottom
)
1304 /*************************************************************************
1306 |* SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab()
1308 |*************************************************************************/
1309 // OD 15.11.2002 #105155# - introduce support for vertical layout
1310 sal_Bool
SwLayAction::FormatLayout( SwLayoutFrm
*pLay
, sal_Bool bAddRect
)
1312 OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
1316 sal_Bool bChanged
= sal_False
;
1317 bool bAlreadyPainted
= false;
1318 // OD 11.11.2002 #104414# - remember frame at complete paint
1319 SwRect aFrmAtCompletePaint
;
1321 if ( !pLay
->IsValid() || pLay
->IsCompletePaint() )
1323 if ( pLay
->GetPrev() && !pLay
->GetPrev()->IsValid() )
1324 pLay
->GetPrev()->SetCompletePaint();
1326 SwRect
aOldFrame( pLay
->Frm() );
1327 SwRect
aOldRect( aOldFrame
);
1328 if( pLay
->IsPageFrm() )
1330 aOldRect
= static_cast<SwPageFrm
*>(pLay
)->GetBoundRect();
1334 if ( aOldFrame
!= pLay
->Frm() )
1335 bChanged
= sal_True
;
1337 bool bNoPaint
= false;
1338 if ( pLay
->IsPageBodyFrm() &&
1339 pLay
->Frm().Pos() == aOldRect
.Pos() &&
1342 const ViewShell
*pSh
= pLay
->getRootFrm()->GetCurrShell();
1343 // Limitations because of headers / footers
1344 if( pSh
&& pSh
->GetViewOptions()->getBrowseMode() &&
1345 !( pLay
->IsCompletePaint() && pLay
->FindPageFrm()->FindFtnCont() ) )
1349 if ( !bNoPaint
&& IsPaint() && bAddRect
&& (pLay
->IsCompletePaint() || bChanged
) )
1351 SwRect
aPaint( pLay
->Frm() );
1352 // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for
1353 // page frames -> enlarge paint rectangle correspondingly.
1354 if ( pLay
->IsPageFrm() )
1356 SwPageFrm
* pPageFrm
= static_cast<SwPageFrm
*>(pLay
);
1357 aPaint
= pPageFrm
->GetBoundRect();
1360 bool bPageInBrowseMode
= pLay
->IsPageFrm();
1361 if( bPageInBrowseMode
)
1363 const ViewShell
*pSh
= pLay
->getRootFrm()->GetCurrShell();
1364 if( !pSh
|| !pSh
->GetViewOptions()->getBrowseMode() )
1365 bPageInBrowseMode
= false;
1367 if( bPageInBrowseMode
)
1369 // NOTE: no vertical layout in online layout
1370 // Is the change even visible?
1371 if ( pLay
->IsCompletePaint() )
1373 pImp
->GetShell()->AddPaintRect( aPaint
);
1374 bAddRect
= sal_False
;
1380 SwRegionRects
aRegion( aOldRect
);
1382 for ( i
= 0; i
< aRegion
.size(); ++i
)
1383 pImp
->GetShell()->AddPaintRect( aRegion
[i
] );
1384 aRegion
.ChangeOrigin( aPaint
);
1386 aRegion
.push_back( aPaint
);
1387 aRegion
-= aOldRect
;
1388 for ( i
= 0; i
< aRegion
.size(); ++i
)
1389 pImp
->GetShell()->AddPaintRect( aRegion
[i
] );
1395 pImp
->GetShell()->AddPaintRect( aPaint
);
1396 bAlreadyPainted
= true;
1397 // OD 11.11.2002 #104414# - remember frame at complete paint
1398 aFrmAtCompletePaint
= pLay
->Frm();
1401 // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing
1402 // between pages (not only for in online mode).
1403 if ( pLay
->IsPageFrm() )
1405 const SwTwips nHalfDocBorder
= GAPBETWEENPAGES
;
1406 const bool bLeftToRightViewLayout
= pRoot
->IsLeftToRightViewLayout();
1407 const bool bPrev
= bLeftToRightViewLayout
? pLay
->GetPrev() : pLay
->GetNext();
1408 const bool bNext
= bLeftToRightViewLayout
? pLay
->GetNext() : pLay
->GetPrev();
1409 SwPageFrm
* pPageFrm
= static_cast<SwPageFrm
*>(pLay
);
1410 const ViewShell
*pSh
= pLay
->getRootFrm()->GetCurrShell();
1411 SwRect
aPageRect( pLay
->Frm() );
1415 SwPageFrm::GetBorderAndShadowBoundRect(aPageRect
, pSh
,
1416 aPageRect
, pPageFrm
->IsLeftShadowNeeded(), pPageFrm
->IsRightShadowNeeded(),
1417 pPageFrm
->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT
);
1423 SwRect
aSpaceToPrevPage( aPageRect
);
1424 aSpaceToPrevPage
.Top( aSpaceToPrevPage
.Top() - nHalfDocBorder
);
1425 aSpaceToPrevPage
.Bottom( pLay
->Frm().Top() );
1426 if(aSpaceToPrevPage
.Height() > 0 && aSpaceToPrevPage
.Width() > 0)
1427 pImp
->GetShell()->AddPaintRect( aSpaceToPrevPage
);
1429 pSh
->GetOut()->DrawRect( aSpaceToPrevPage
.SVRect() );
1432 aSpaceToPrevPage
= aPageRect
;
1433 aSpaceToPrevPage
.Left( aSpaceToPrevPage
.Left() - nHalfDocBorder
);
1434 aSpaceToPrevPage
.Right( pLay
->Frm().Left() );
1435 if(aSpaceToPrevPage
.Height() > 0 && aSpaceToPrevPage
.Width() > 0)
1436 pImp
->GetShell()->AddPaintRect( aSpaceToPrevPage
);
1441 SwRect
aSpaceToNextPage( aPageRect
);
1442 aSpaceToNextPage
.Bottom( aSpaceToNextPage
.Bottom() + nHalfDocBorder
);
1443 aSpaceToNextPage
.Top( pLay
->Frm().Bottom() );
1444 if(aSpaceToNextPage
.Height() > 0 && aSpaceToNextPage
.Width() > 0)
1445 pImp
->GetShell()->AddPaintRect( aSpaceToNextPage
);
1448 aSpaceToNextPage
= aPageRect
;
1449 aSpaceToNextPage
.Right( aSpaceToNextPage
.Right() + nHalfDocBorder
);
1450 aSpaceToNextPage
.Left( pLay
->Frm().Right() );
1451 if(aSpaceToNextPage
.Height() > 0 && aSpaceToNextPage
.Width() > 0)
1452 pImp
->GetShell()->AddPaintRect( aSpaceToNextPage
);
1456 pLay
->ResetCompletePaint();
1459 if ( IsPaint() && bAddRect
&&
1460 !pLay
->GetNext() && pLay
->IsRetoucheFrm() && pLay
->IsRetouche() )
1462 // OD 15.11.2002 #105155# - vertical layout support
1464 SwRect
aRect( pLay
->GetUpper()->PaintArea() );
1465 (aRect
.*fnRect
->fnSetTop
)( (pLay
->*fnRect
->fnGetPrtBottom
)() );
1466 if ( !pImp
->GetShell()->AddPaintRect( aRect
) )
1467 pLay
->ResetRetouche();
1470 if( bAlreadyPainted
)
1471 bAddRect
= sal_False
;
1478 // Now, deal with the lowers that are LayoutFrms
1480 if ( pLay
->IsFtnFrm() ) // no LayFrms as Lower
1483 SwFrm
*pLow
= pLay
->Lower();
1484 sal_Bool bTabChanged
= sal_False
;
1485 while ( pLow
&& pLow
->GetUpper() == pLay
)
1487 if ( pLow
->IsLayoutFrm() )
1489 if ( pLow
->IsTabFrm() )
1490 bTabChanged
|= FormatLayoutTab( (SwTabFrm
*)pLow
, bAddRect
);
1491 // Skip the ones already registered for deletion
1492 else if( !pLow
->IsSctFrm() || ((SwSectionFrm
*)pLow
)->GetSection() )
1493 bChanged
|= FormatLayout( (SwLayoutFrm
*)pLow
, bAddRect
);
1495 else if ( pImp
->GetShell()->IsPaintLocked() )
1496 // Shortcut to minimize the cycles. With Lock, the
1497 // paint is coming either way (primarily for browse)
1502 pLow
= pLow
->GetNext();
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
1507 SwRect
aBoundRect(pLay
->IsPageFrm() ? static_cast<SwPageFrm
*>(pLay
)->GetBoundRect() : pLay
->Frm() );
1509 if ( bAlreadyPainted
&&
1510 ( aBoundRect
.Width() > aFrmAtCompletePaint
.Width() ||
1511 aBoundRect
.Height() > aFrmAtCompletePaint
.Height() )
1514 pImp
->GetShell()->AddPaintRect( aBoundRect
);
1516 return bChanged
|| bTabChanged
;
1519 sal_Bool
SwLayAction::FormatLayoutFly( SwFlyFrm
* pFly
)
1521 OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
1525 sal_Bool bChanged
= false;
1526 sal_Bool bAddRect
= true;
1528 if ( !pFly
->IsValid() || pFly
->IsCompletePaint() || pFly
->IsInvalid() )
1530 // The Frame has changed, now it's getting formatted.
1531 const SwRect
aOldRect( pFly
->Frm() );
1533 bChanged
= aOldRect
!= pFly
->Frm();
1535 if ( IsPaint() && (pFly
->IsCompletePaint() || bChanged
) &&
1536 pFly
->Frm().Top() > 0 && pFly
->Frm().Left() > 0 )
1537 pImp
->GetShell()->AddPaintRect( pFly
->Frm() );
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() );
1552 pFly
->ResetCompletePaint();
1558 // Now, deal with the lowers that are LayoutFrms
1559 sal_Bool bTabChanged
= false;
1560 SwFrm
*pLow
= pFly
->Lower();
1563 if ( pLow
->IsLayoutFrm() )
1565 if ( pLow
->IsTabFrm() )
1566 bTabChanged
|= FormatLayoutTab( (SwTabFrm
*)pLow
, bAddRect
);
1568 bChanged
|= FormatLayout( (SwLayoutFrm
*)pLow
, bAddRect
);
1570 pLow
= pLow
->GetNext();
1572 return bChanged
|| bTabChanged
;
1575 // OD 31.10.2002 #104100#
1576 // Implement vertical layout support
1577 sal_Bool
SwLayAction::FormatLayoutTab( SwTabFrm
*pTab
, sal_Bool bAddRect
)
1579 OSL_ENSURE( !IsAgain(), "8-) Attention to the invalid page." );
1580 if ( IsAgain() || !pTab
->Lower() )
1583 IDocumentTimerAccess
*pTimerAccess
= pRoot
->GetFmt()->getIDocumentTimerAccess();
1584 pTimerAccess
->BlockIdling();
1586 sal_Bool bChanged
= sal_False
;
1587 bool bPainted
= false;
1589 const SwPageFrm
*pOldPage
= pTab
->FindPageFrm();
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>.
1596 if ( !pTab
->IsValid() || pTab
->IsCompletePaint() || pTab
->IsComplete() )
1598 if ( pTab
->GetPrev() && !pTab
->GetPrev()->IsValid() )
1600 pTab
->GetPrev()->SetCompletePaint();
1603 const SwRect
aOldRect( pTab
->Frm() );
1604 pTab
->SetLowersFormatted( sal_False
);
1606 if ( aOldRect
!= pTab
->Frm() )
1608 bChanged
= sal_True
;
1610 const SwRect aPaintFrm
= pTab
->PaintArea();
1612 if ( IsPaint() && bAddRect
)
1614 // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()>
1615 if ( !pTab
->IsCompletePaint() &&
1616 pTab
->IsComplete() &&
1617 ( pTab
->Frm().SSize() != pTab
->Prt().SSize() ||
1618 // OD 31.10.2002 #104100# - vertical layout support
1619 (pTab
->*fnRect
->fnGetLeftMargin
)() ) &&
1620 pTab
->Frm().HasArea()
1623 // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles.
1626 SwTwips nLeftMargin
= (pTab
->*fnRect
->fnGetLeftMargin
)();
1627 if ( nLeftMargin
> 0)
1629 aMarginRect
= pTab
->Frm();
1630 (aMarginRect
.*fnRect
->fnSetWidth
)( nLeftMargin
);
1631 pImp
->GetShell()->AddPaintRect( aMarginRect
);
1634 if ( (pTab
->*fnRect
->fnGetRightMargin
)() > 0)
1636 aMarginRect
= pTab
->Frm();
1637 (aMarginRect
.*fnRect
->fnSetLeft
)( (pTab
->*fnRect
->fnGetPrtRight
)() );
1638 pImp
->GetShell()->AddPaintRect( aMarginRect
);
1641 SwTwips nTopMargin
= (pTab
->*fnRect
->fnGetTopMargin
)();
1642 if ( nTopMargin
> 0)
1644 aMarginRect
= pTab
->Frm();
1645 (aMarginRect
.*fnRect
->fnSetHeight
)( nTopMargin
);
1646 pImp
->GetShell()->AddPaintRect( aMarginRect
);
1649 if ( (pTab
->*fnRect
->fnGetBottomMargin
)() > 0)
1651 aMarginRect
= pTab
->Frm();
1652 (aMarginRect
.*fnRect
->fnSetTop
)( (pTab
->*fnRect
->fnGetPrtBottom
)() );
1653 pImp
->GetShell()->AddPaintRect( aMarginRect
);
1656 else if ( pTab
->IsCompletePaint() )
1658 pImp
->GetShell()->AddPaintRect( aPaintFrm
);
1659 bAddRect
= sal_False
;
1663 if ( pTab
->IsRetouche() && !pTab
->GetNext() )
1665 SwRect
aRect( pTab
->GetUpper()->PaintArea() );
1666 // OD 04.11.2002 #104100# - vertical layout support
1667 (aRect
.*fnRect
->fnSetTop
)( (pTab
->*fnRect
->fnGetPrtBottom
)() );
1668 if ( !pImp
->GetShell()->AddPaintRect( aRect
) )
1669 pTab
->ResetRetouche();
1673 bAddRect
= sal_False
;
1675 if ( pTab
->IsCompletePaint() && !pOptTab
)
1677 pTab
->ResetCompletePaint();
1679 if ( IsPaint() && bAddRect
&& pTab
->IsRetouche() && !pTab
->GetNext() )
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 SwRect
aRect( pTab
->GetUpper()->PaintArea() );
1685 // OD 04.11.2002 #104100# - vertical layout support
1686 (aRect
.*fnRect
->fnSetTop
)( (pTab
->*fnRect
->fnGetPrtBottom
)() );
1687 if ( !pImp
->GetShell()->AddPaintRect( aRect
) )
1688 pTab
->ResetRetouche();
1693 pTimerAccess
->UnblockIdling();
1696 if ( pTab
->IsLowersFormatted() &&
1697 (bPainted
|| !pImp
->GetShell()->VisArea().IsOver( pTab
->Frm())) )
1700 // Now, deal with the lowers
1704 // OD 20.10.2003 #112464# - for savety reasons:
1705 // check page number before formatting lowers.
1706 if ( pOldPage
->GetPhyPageNum() > (pTab
->FindPageFrm()->GetPhyPageNum() + 1) )
1707 SetNextCycle( sal_True
);
1709 // OD 20.10.2003 #112464# - format lowers, only if table frame is valid
1710 if ( pTab
->IsValid() )
1712 SwLayoutFrm
*pLow
= (SwLayoutFrm
*)pTab
->Lower();
1715 bChanged
|= FormatLayout( (SwLayoutFrm
*)pLow
, bAddRect
);
1718 pLow
= (SwLayoutFrm
*)pLow
->GetNext();
1725 /*************************************************************************
1727 |* SwLayAction::FormatCntnt()
1729 |*************************************************************************/
1730 sal_Bool
SwLayAction::FormatCntnt( const SwPageFrm
*pPage
)
1732 const SwCntntFrm
*pCntnt
= pPage
->ContainsCntnt();
1733 const ViewShell
*pSh
= pRoot
->GetCurrShell();
1734 const bool bBrowse
= pSh
&& pSh
->GetViewOptions()->getBrowseMode();
1736 while ( pCntnt
&& pPage
->IsAnLower( pCntnt
) )
1738 // If the Cntnt didn't change, we can use a few shortcuts.
1739 const bool bFull
= !pCntnt
->IsValid() || pCntnt
->IsCompletePaint() ||
1740 pCntnt
->IsRetouche() || pCntnt
->GetDrawObjs();
1743 // We do this so we don't have to search later on.
1744 const bool bNxtCnt
= IsCalcLayout() && !pCntnt
->GetFollow();
1745 const SwCntntFrm
*pCntntNext
= bNxtCnt
? pCntnt
->GetNextCntntFrm() : 0;
1746 const SwCntntFrm
*pCntntPrev
= pCntnt
->GetPrev() ? pCntnt
->GetPrevCntntFrm() : 0;
1748 const SwLayoutFrm
*pOldUpper
= pCntnt
->GetUpper();
1749 const SwTabFrm
*pTab
= pCntnt
->FindTabFrm();
1750 const bool bInValid
= !pCntnt
->IsValid() || pCntnt
->IsCompletePaint();
1751 const sal_Bool bOldPaint
= IsPaint();
1752 bPaint
= bOldPaint
&& !(pTab
&& pTab
== pOptTab
);
1753 _FormatCntnt( pCntnt
, pPage
);
1754 // #i26945# - reset <bPaint> before format objects
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.
1764 ( !IsInterrupt() || mbFormatCntntOnInterrupt
) &&
1765 pCntnt
->IsTxtFrm() &&
1766 !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm
*>(pCntnt
)),
1767 *(pCntnt
->FindPageFrm()), this ) )
1772 if ( !pCntnt
->GetValidLineNumFlag() && pCntnt
->IsTxtFrm() )
1774 const sal_uLong nAllLines
= ((SwTxtFrm
*)pCntnt
)->GetAllLines();
1775 ((SwTxtFrm
*)pCntnt
)->RecalcAllLines();
1776 if ( IsPaintExtraData() && IsPaint() &&
1777 nAllLines
!= ((SwTxtFrm
*)pCntnt
)->GetAllLines() )
1778 pImp
->GetShell()->AddPaintRect( pCntnt
->Frm() );
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 if ( (!pTab
|| (pTab
&& !bInValid
)) )
1792 // OD 14.04.2003 #106346# - consider interrupt formatting.
1793 if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt
) ||
1794 ( !bBrowse
&& pPage
->IsInvalidLayout() ) ||
1795 // OD 07.05.2003 #109435# - consider interrupt formatting
1796 ( IS_FLYS
&& IS_INVAFLY
&& !mbFormatCntntOnInterrupt
)
1800 if ( pOldUpper
!= pCntnt
->GetUpper() )
1802 const sal_uInt16 nCurNum
= pCntnt
->FindPageFrm()->GetPhyPageNum();
1803 if ( nCurNum
< pPage
->GetPhyPageNum() )
1804 nPreInvaPage
= nCurNum
;
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 if ( !IsCalcLayout() && pPage
->GetPhyPageNum() > nCurNum
+1 )
1810 SetNextCycle( sal_True
);
1811 // OD 07.05.2003 #109435# - consider interrupt formatting
1812 if ( !mbFormatCntntOnInterrupt
)
1818 // If the Frame moved forwards to the next page, we re-run through
1820 // This way, we catch predecessors which are now responsible for
1821 // retouching, but the footers will be touched also.
1822 bool bSetCntnt
= true;
1825 if ( !pCntntPrev
->IsValid() && pPage
->IsAnLower( pCntntPrev
) )
1826 pPage
->InvalidateCntnt();
1827 if ( pOldUpper
!= pCntnt
->GetUpper() &&
1828 pPage
->GetPhyPageNum() < pCntnt
->FindPageFrm()->GetPhyPageNum() )
1830 pCntnt
= pCntntPrev
;
1836 if ( bBrowse
&& !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1837 pCntnt
->Frm().Top() > pImp
->GetShell()->VisArea().Bottom())
1839 const long nBottom
= pImp
->GetShell()->VisArea().Bottom();
1840 const SwFrm
*pTmp
= lcl_FindFirstInvaCntnt( pPage
,
1844 if ( (!(IS_FLYS
&& IS_INVAFLY
) ||
1845 !lcl_FindFirstInvaObj( pPage
, nBottom
)) &&
1846 (!pPage
->IsInvalidLayout() ||
1847 !lcl_FindFirstInvaLay( pPage
, nBottom
)))
1848 SetBrowseActionStop( sal_True
);
1849 // OD 14.04.2003 #106346# - consider interrupt formatting.
1850 if ( !mbFormatCntntOnInterrupt
)
1856 pCntnt
= bNxtCnt
? pCntntNext
: pCntnt
->GetNextCntntFrm();
1863 if ( !pCntnt
->GetValidLineNumFlag() && pCntnt
->IsTxtFrm() )
1865 const sal_uLong nAllLines
= ((SwTxtFrm
*)pCntnt
)->GetAllLines();
1866 ((SwTxtFrm
*)pCntnt
)->RecalcAllLines();
1867 if ( IsPaintExtraData() && IsPaint() &&
1868 nAllLines
!= ((SwTxtFrm
*)pCntnt
)->GetAllLines() )
1869 pImp
->GetShell()->AddPaintRect( pCntnt
->Frm() );
1872 // Do this if the Frm has been formatted before.
1873 if ( pCntnt
->IsTxtFrm() && ((SwTxtFrm
*)pCntnt
)->HasRepaint() &&
1875 PaintCntnt( pCntnt
, pPage
, pCntnt
->Frm(), pCntnt
->Frm().Bottom());
1879 // OD 14.04.2003 #106346# - consider interrupt formatting.
1880 if ( IsInterrupt() && !mbFormatCntntOnInterrupt
)
1883 if ( bBrowse
&& !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1884 pCntnt
->Frm().Top() > pImp
->GetShell()->VisArea().Bottom())
1886 const long nBottom
= pImp
->GetShell()->VisArea().Bottom();
1887 const SwFrm
*pTmp
= lcl_FindFirstInvaCntnt( pPage
,
1891 if ( (!(IS_FLYS
&& IS_INVAFLY
) ||
1892 !lcl_FindFirstInvaObj( pPage
, nBottom
)) &&
1893 (!pPage
->IsInvalidLayout() ||
1894 !lcl_FindFirstInvaLay( pPage
, nBottom
)))
1895 SetBrowseActionStop( sal_True
);
1896 // OD 14.04.2003 #106346# - consider interrupt formatting.
1897 if ( !mbFormatCntntOnInterrupt
)
1903 pCntnt
= pCntnt
->GetNextCntntFrm();
1907 // OD 14.04.2003 #106346# - consider interrupt formatting.
1908 return !IsInterrupt() || mbFormatCntntOnInterrupt
;
1910 /*************************************************************************
1912 |* SwLayAction::_FormatCntnt()
1914 |* Description Returns sal_True if the paragraph has been processed,
1915 |* sal_False if there wasn't anything to be processed.
1917 |*************************************************************************/
1918 void SwLayAction::_FormatCntnt( const SwCntntFrm
*pCntnt
,
1919 const SwPageFrm
*pPage
)
1921 // We probably only ended up here because the Cntnt holds DrawObjects.
1922 const bool bDrawObjsOnly
= pCntnt
->IsValid() && !pCntnt
->IsCompletePaint() &&
1923 !pCntnt
->IsRetouche();
1925 if ( !bDrawObjsOnly
&& IsPaint() )
1927 const SwRect
aOldRect( pCntnt
->UnionFrm() );
1928 const long nOldBottom
= (pCntnt
->*fnRect
->fnGetPrtBottom
)();
1932 if( (*fnRect
->fnYDiff
)( (pCntnt
->Frm().*fnRect
->fnGetBottom
)(),
1933 (aOldRect
.*fnRect
->fnGetBottom
)() ) < 0 )
1935 pCntnt
->SetRetouche();
1937 PaintCntnt( pCntnt
, pCntnt
->FindPageFrm(), aOldRect
, nOldBottom
);
1941 if ( IsPaint() && pCntnt
->IsTxtFrm() && ((SwTxtFrm
*)pCntnt
)->HasRepaint() )
1942 PaintCntnt( pCntnt
, pPage
, pCntnt
->Frm(),
1943 (pCntnt
->Frm().*fnRect
->fnGetBottom
)() );
1948 /*************************************************************************
1950 |* SwLayAction::_FormatFlyCntnt()
1953 |* - Returns sal_True if all Cntnts of the Fly have been processed completely.
1954 |* Returns sal_False if processing has been interrupted prematurely.
1956 |*************************************************************************/
1957 sal_Bool
SwLayAction::_FormatFlyCntnt( const SwFlyFrm
*pFly
)
1959 const SwCntntFrm
*pCntnt
= pFly
->ContainsCntnt();
1963 // OD 2004-05-10 #i28701#
1964 _FormatCntnt( pCntnt
, pCntnt
->FindPageFrm() );
1966 // #i28701# - format floating screen objects
1967 // at content text frame
1968 // #i23129#, #i36347# - pass correct page frame
1969 // to the object formatter.
1970 if ( pCntnt
->IsTxtFrm() &&
1971 !SwObjectFormatter::FormatObjsAtFrm(
1972 *(const_cast<SwCntntFrm
*>(pCntnt
)),
1973 *(pCntnt
->FindPageFrm()), this ) )
1975 // restart format with first content
1976 pCntnt
= pFly
->ContainsCntnt();
1980 if ( !pCntnt
->GetValidLineNumFlag() && pCntnt
->IsTxtFrm() )
1982 const sal_uLong nAllLines
= ((SwTxtFrm
*)pCntnt
)->GetAllLines();
1983 ((SwTxtFrm
*)pCntnt
)->RecalcAllLines();
1984 if ( IsPaintExtraData() && IsPaint() &&
1985 nAllLines
!= ((SwTxtFrm
*)pCntnt
)->GetAllLines() )
1986 pImp
->GetShell()->AddPaintRect( pCntnt
->Frm() );
1992 // If there's input, we interrupt processing.
1993 if ( !pFly
->IsFlyInCntFrm() )
1996 // OD 14.04.2003 #106346# - consider interrupt formatting.
1997 if ( IsInterrupt() && !mbFormatCntntOnInterrupt
)
2000 pCntnt
= pCntnt
->GetNextCntntFrm();
2003 // OD 14.04.2003 #106346# - consider interrupt formatting.
2004 return !(IsInterrupt() && !mbFormatCntntOnInterrupt
);
2007 sal_Bool
SwLayAction::IsStopPrt() const
2009 sal_Bool bResult
= sal_False
;
2011 if (pImp
!= NULL
&& pProgress
!= NULL
)
2012 bResult
= pImp
->IsStopPrt();
2017 /*************************************************************************
2019 |* SwLayAction::FormatSpelling(), _FormatSpelling()
2021 |*************************************************************************/
2022 sal_Bool
SwLayIdle::_DoIdleJob( const SwCntntFrm
*pCnt
, IdleJobType eJob
)
2024 OSL_ENSURE( pCnt
->IsTxtFrm(), "NoTxt neighbour of Txt" );
2025 // robust against misuse by e.g. #i52542#
2026 if( !pCnt
->IsTxtFrm() )
2029 const SwTxtNode
* pTxtNode
= pCnt
->GetNode()->GetTxtNode();
2031 bool bProcess
= false;
2034 case ONLINE_SPELLING
:
2035 bProcess
= pTxtNode
->IsWrongDirty(); break;
2036 case AUTOCOMPLETE_WORDS
:
2037 bProcess
= pTxtNode
->IsAutoCompleteWordDirty(); break;
2039 bProcess
= pTxtNode
->IsWordCountDirty(); break;
2040 case SMART_TAGS
: // SMARTTAGS
2041 bProcess
= pTxtNode
->IsSmartTagDirty(); break;
2046 ViewShell
*pSh
= pImp
->GetShell();
2047 if( STRING_LEN
== nTxtPos
)
2050 if( pSh
->ISA(SwCrsrShell
) && !((SwCrsrShell
*)pSh
)->IsTableMode() )
2052 SwPaM
*pCrsr
= ((SwCrsrShell
*)pSh
)->GetCrsr();
2053 if( !pCrsr
->HasMark() && pCrsr
== pCrsr
->GetNext() )
2055 pCntntNode
= pCrsr
->GetCntntNode();
2056 nTxtPos
= pCrsr
->GetPoint()->nContent
.GetIndex();
2063 case ONLINE_SPELLING
:
2065 SwRect
aRepaint( ((SwTxtFrm
*)pCnt
)->_AutoSpell( pCntntNode
, *pSh
->GetViewOptions(), nTxtPos
) );
2066 bPageValid
= bPageValid
&& !pTxtNode
->IsWrongDirty();
2068 bAllValid
= sal_False
;
2069 if ( aRepaint
.HasArea() )
2070 pImp
->GetShell()->InvalidateWindows( aRepaint
);
2071 if ( Application::AnyInput( VCL_INPUT_MOUSEANDKEYBOARD
|VCL_INPUT_OTHER
|VCL_INPUT_PAINT
) )
2075 case AUTOCOMPLETE_WORDS
:
2076 ((SwTxtFrm
*)pCnt
)->CollectAutoCmplWrds( pCntntNode
, nTxtPos
);
2077 if ( Application::AnyInput( VCL_INPUT_ANY
) )
2082 const xub_StrLen nEnd
= pTxtNode
->GetTxt().getLength();
2084 pTxtNode
->CountWords( aStat
, 0, nEnd
);
2085 if ( Application::AnyInput( VCL_INPUT_ANY
) )
2089 case SMART_TAGS
: // SMARTTAGS
2091 const SwRect
aRepaint( ((SwTxtFrm
*)pCnt
)->SmartTagScan( pCntntNode
, nTxtPos
) );
2092 bPageValid
= bPageValid
&& !pTxtNode
->IsSmartTagDirty();
2094 bAllValid
= sal_False
;
2095 if ( aRepaint
.HasArea() )
2096 pImp
->GetShell()->InvalidateWindows( aRepaint
);
2097 if ( Application::AnyInput( VCL_INPUT_MOUSEANDKEYBOARD
|VCL_INPUT_OTHER
|VCL_INPUT_PAINT
) )
2104 // The Flys that are anchored to the paragraph need to be considered too.
2105 if ( pCnt
->GetDrawObjs() )
2107 const SwSortedObjs
&rObjs
= *pCnt
->GetDrawObjs();
2108 for ( sal_uInt16 i
= 0; i
< rObjs
.Count(); ++i
)
2110 SwAnchoredObject
* pObj
= rObjs
[i
];
2111 if ( pObj
->ISA(SwFlyFrm
) )
2113 SwFlyFrm
* pFly
= static_cast<SwFlyFrm
*>(pObj
);
2114 if ( pFly
->IsFlyInCntFrm() )
2116 const SwCntntFrm
*pC
= pFly
->ContainsCntnt();
2119 if ( pC
->IsTxtFrm() )
2121 if ( _DoIdleJob( pC
, eJob
) )
2124 pC
= pC
->GetNextCntntFrm();
2133 sal_Bool
SwLayIdle::DoIdleJob( IdleJobType eJob
, sal_Bool bVisAreaOnly
)
2135 // Spellcheck all contents of the pages. Either only the
2136 // visible ones or all of them.
2137 const ViewShell
* pViewShell
= pImp
->GetShell();
2138 const SwViewOption
* pViewOptions
= pViewShell
->GetViewOptions();
2139 const SwDoc
* pDoc
= pViewShell
->GetDoc();
2143 case ONLINE_SPELLING
:
2144 if( !pViewOptions
->IsOnlineSpell() )
2147 case AUTOCOMPLETE_WORDS
:
2148 if( !pViewOptions
->IsAutoCompleteWords() ||
2149 pDoc
->GetAutoCompleteWords().IsLockWordLstLocked())
2153 if ( !pViewShell
->getIDocumentStatistics()->GetDocStat().bModified
)
2157 if ( pDoc
->GetDocShell()->IsHelpDocument() ||
2159 !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
2162 default: OSL_FAIL( "Unknown idle job type" );
2167 pPage
= pImp
->GetFirstVisPage();
2169 pPage
= (SwPageFrm
*)pRoot
->Lower();
2172 nTxtPos
= STRING_LEN
;
2176 bPageValid
= sal_True
;
2177 const SwCntntFrm
*pCnt
= pPage
->ContainsCntnt();
2178 while( pCnt
&& pPage
->IsAnLower( pCnt
) )
2180 if ( _DoIdleJob( pCnt
, eJob
) )
2182 pCnt
= pCnt
->GetNextCntntFrm();
2184 if ( pPage
->GetSortedObjs() )
2186 for ( sal_uInt16 i
= 0; pPage
->GetSortedObjs() &&
2187 i
< pPage
->GetSortedObjs()->Count(); ++i
)
2189 const SwAnchoredObject
* pObj
= (*pPage
->GetSortedObjs())[i
];
2190 if ( pObj
->ISA(SwFlyFrm
) )
2192 const SwFlyFrm
*pFly
= static_cast<const SwFlyFrm
*>(pObj
);
2193 const SwCntntFrm
*pC
= pFly
->ContainsCntnt();
2196 if ( pC
->IsTxtFrm() )
2198 if ( _DoIdleJob( pC
, eJob
) )
2201 pC
= pC
->GetNextCntntFrm();
2211 case ONLINE_SPELLING
: pPage
->ValidateSpelling(); break;
2212 case AUTOCOMPLETE_WORDS
: pPage
->ValidateAutoCompleteWords(); break;
2213 case WORD_COUNT
: pPage
->ValidateWordCount(); break;
2214 case SMART_TAGS
: pPage
->ValidateSmartTags(); break; // SMARTTAGS
2218 pPage
= (SwPageFrm
*)pPage
->GetNext();
2219 if ( pPage
&& bVisAreaOnly
&&
2220 !pPage
->Frm().IsOver( pImp
->GetShell()->VisArea()))
2227 /*************************************************************************
2229 |* void SwLayIdle::SwLayIdle()
2231 |*************************************************************************/
2232 void SwLayIdle::ShowIdle( ColorData eColorData
)
2234 if ( !m_bIndicator
)
2236 m_bIndicator
= true;
2237 Window
*pWin
= pImp
->GetShell()->GetWin();
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
);
2251 #define SHOW_IDLE( ColorData ) ShowIdle( ColorData )
2253 #define SHOW_IDLE( ColorData )
2256 /*************************************************************************
2258 |* void SwLayIdle::SwLayIdle()
2260 |*************************************************************************/
2261 SwLayIdle::SwLayIdle( SwRootFrm
*pRt
, SwViewImp
*pI
) :
2265 , m_bIndicator( false )
2268 pImp
->pIdleAct
= this;
2270 SHOW_IDLE( COL_LIGHTRED
);
2272 pImp
->GetShell()->EnableSmooth( sal_False
);
2274 // First, spellcheck the visible area. Only if there's nothing
2275 // to do there, we trigger the IdleFormat.
2276 if ( !DoIdleJob( SMART_TAGS
, sal_True
) &&
2277 !DoIdleJob( ONLINE_SPELLING
, sal_True
) &&
2278 !DoIdleJob( AUTOCOMPLETE_WORDS
, sal_True
) ) // SMARTTAGS
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 std::vector
<bool> aBools
;
2286 ViewShell
*pSh
= pImp
->GetShell();
2288 { ++pSh
->mnStartAction
;
2289 sal_Bool bVis
= sal_False
;
2290 if ( pSh
->ISA(SwCrsrShell
) )
2292 bVis
= ((SwCrsrShell
*)pSh
)->GetCharRect().IsOver(pSh
->VisArea());
2294 aBools
.push_back( bVis
);
2295 pSh
= (ViewShell
*)pSh
->GetNext();
2296 } while ( pSh
!= pImp
->GetShell() );
2298 SwLayAction
aAction( pRoot
, pImp
);
2299 aAction
.SetInputType( VCL_INPUT_ANY
);
2300 aAction
.SetIdle( sal_True
);
2301 aAction
.SetWaitAllowed( sal_False
);
2304 // Further start/end actions only happen if there were paints started
2305 // somewhere or if the visibility of the CharRects has changed.
2306 sal_Bool bActions
= sal_False
;
2307 sal_uInt16 nBoolIdx
= 0;
2310 --pSh
->mnStartAction
;
2312 if ( pSh
->Imp()->GetRegion() )
2313 bActions
= sal_True
;
2316 SwRect
aTmp( pSh
->VisArea() );
2317 pSh
->UISizeNotify();
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() );
2324 // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!)
2325 // and the cursor is visible.
2326 bActions
|= aTmp
!= pSh
->VisArea();
2327 if ( aTmp
== pSh
->VisArea() && pSh
->ISA(SwCrsrShell
) )
2329 bActions
|= ((sal_Bool
) aBools
[nBoolIdx
]) !=
2330 static_cast<SwCrsrShell
*>(pSh
)->GetCharRect().IsOver( pSh
->VisArea() );
2334 pSh
= (ViewShell
*)pSh
->GetNext();
2336 } while ( pSh
!= pImp
->GetShell() );
2340 // Prepare start/end actions via CrsrShell, so the cursor, selection
2341 // and VisArea can be set correctly.
2345 sal_Bool bCrsrShell
= pSh
->IsA( TYPE(SwCrsrShell
) );
2348 ((SwCrsrShell
*)pSh
)->SttCrsrMove();
2350 // pSh->StartAction();
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.
2356 SwViewImp
*pViewImp
= pSh
->Imp();
2357 bool bUnlock
= false;
2358 if ( pViewImp
->GetRegion() )
2360 pViewImp
->DelRegion();
2362 // Cause a repaint with virtual device.
2368 // If the Crsr was visible, we need to make it visible again.
2369 // Otherwise, EndCrsrMove with sal_True for IdleEnd
2370 ((SwCrsrShell
*)pSh
)->EndCrsrMove( sal_True
^aBools
[nBoolIdx
] );
2372 // pSh->EndAction();
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 ((SwCrsrShell
*)pSh
)->ShLooseFcs();
2383 pSh
->UnlockPaint( sal_True
);
2384 ((SwCrsrShell
*)pSh
)->ShGetFcs( sal_False
);
2387 pSh
->UnlockPaint( sal_True
);
2390 pSh
= (ViewShell
*)pSh
->GetNext();
2393 } while ( pSh
!= pImp
->GetShell() );
2396 if ( !aAction
.IsInterrupt() )
2398 if ( !DoIdleJob( WORD_COUNT
, sal_False
) )
2399 if ( !DoIdleJob( SMART_TAGS
, sal_False
) )
2400 if ( !DoIdleJob( ONLINE_SPELLING
, sal_False
) )
2401 DoIdleJob( AUTOCOMPLETE_WORDS
, sal_False
); // SMARTTAGS
2404 bool bInValid
= false;
2405 const SwViewOption
& rVOpt
= *pImp
->GetShell()->GetViewOptions();
2406 const ViewShell
* pViewShell
= pImp
->GetShell();
2407 // See conditions in DoIdleJob()
2408 const sal_Bool bSpell
= rVOpt
.IsOnlineSpell();
2409 const sal_Bool bACmplWrd
= rVOpt
.IsAutoCompleteWords();
2410 const sal_Bool bWordCount
= pViewShell
->getIDocumentStatistics()->GetDocStat().bModified
;
2411 const bool bSmartTags
= !pViewShell
->GetDoc()->GetDocShell()->IsHelpDocument() &&
2412 !pViewShell
->GetDoc()->isXForms() &&
2413 SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
2415 SwPageFrm
*pPg
= (SwPageFrm
*)pRoot
->Lower();
2418 bInValid
= pPg
->IsInvalidCntnt() || pPg
->IsInvalidLayout() ||
2419 pPg
->IsInvalidFlyCntnt() || pPg
->IsInvalidFlyLayout() ||
2420 pPg
->IsInvalidFlyInCnt() ||
2421 (bSpell
&& pPg
->IsInvalidSpelling()) ||
2422 (bACmplWrd
&& pPg
->IsInvalidAutoCompleteWords()) ||
2423 (bWordCount
&& pPg
->IsInvalidWordCount()) ||
2424 (bSmartTags
&& pPg
->IsInvalidSmartTags()); // SMARTTAGS
2426 pPg
= (SwPageFrm
*)pPg
->GetNext();
2428 } while ( pPg
&& !bInValid
);
2432 pRoot
->ResetIdleFormat();
2433 SfxObjectShell
* pDocShell
= pImp
->GetShell()->GetDoc()->GetDocShell();
2434 pDocShell
->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED
, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED
), pDocShell
) );
2438 pImp
->GetShell()->EnableSmooth( sal_True
);
2440 if( pImp
->IsAccessible() )
2441 pImp
->FireAccessibleEvents();
2444 if ( m_bIndicator
&& pImp
->GetShell()->GetWin() )
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
);
2454 SwLayIdle::~SwLayIdle()
2459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */