summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/layact.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/layact.cxx')
-rw-r--r--sw/source/core/layout/layact.cxx2599
1 files changed, 2599 insertions, 0 deletions
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
new file mode 100644
index 000000000000..b51b2efc0a51
--- /dev/null
+++ b/sw/source/core/layout/layact.cxx
@@ -0,0 +1,2599 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+
+#include <time.h>
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "cntfrm.hxx"
+#include "doc.hxx"
+#include "IDocumentDrawModelAccess.hxx"
+#include "IDocumentSettingAccess.hxx"
+#include "IDocumentLayoutAccess.hxx"
+#include "IDocumentStatistics.hxx"
+#include "IDocumentTimerAccess.hxx"
+#include "viewimp.hxx"
+#include "crsrsh.hxx"
+#include "dflyobj.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "dcontact.hxx"
+#include "ndtxt.hxx" // OnlineSpelling
+#include "frmfmt.hxx"
+#include "swregion.hxx"
+#include "viewopt.hxx" // OnlineSpelling ueber Internal-TabPage testen.
+#include "pam.hxx" // OnlineSpelling wg. der aktuellen Cursorposition
+#include "dbg_lay.hxx"
+#include "layouter.hxx" // LoopControlling
+#include "docstat.hxx"
+#include "swevent.hxx"
+
+#include <sfx2/event.hxx>
+
+#include <ftnidx.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <SwSmartTagMgr.hxx>
+
+#define _SVSTDARR_BOOLS
+#include <svl/svstdarr.hxx>
+
+#define _LAYACT_CXX
+#include "layact.hxx"
+#include <swwait.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtanchr.hxx>
+#include <tools/shl.hxx>
+#include <sfx2/progress.hxx>
+#ifndef _DOCSH_HXX
+#include <docsh.hxx>
+#endif
+
+#include "swmodule.hxx"
+#include "fmtline.hxx"
+#include "tabfrm.hxx"
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "notxtfrm.hxx"
+#include "flyfrms.hxx"
+#include "mdiexp.hxx"
+#include "fmtornt.hxx"
+#include "sectfrm.hxx"
+#include "lineinfo.hxx"
+#include <acmplwrd.hxx>
+// --> OD 2004-06-28 #i28701#
+#include <sortedobjs.hxx>
+#include <objectformatter.hxx>
+#include <PostItMgr.hxx>
+
+// <--
+//#pragma optimize("ity",on)
+
+/*************************************************************************
+|*
+|* SwLayAction Statisches Geraffel
+|*
+|* Ersterstellung MA 22. Dec. 93
+|* Letzte Aenderung MA 22. Dec. 93
+|*
+|*************************************************************************/
+
+#define IS_FLYS (pPage->GetSortedObjs())
+#define IS_INVAFLY (pPage->IsInvalidFly())
+
+
+//Sparen von Schreibarbeit um den Zugriff auf zerstoerte Seiten zu vermeiden.
+#ifdef DBG_UTIL
+
+static void BreakPoint()
+{
+ return;
+}
+
+#define CHECKPAGE \
+ { if ( IsAgain() ) \
+ { BreakPoint(); \
+ return; \
+ } \
+ }
+
+#define XCHECKPAGE \
+ { if ( IsAgain() ) \
+ { BreakPoint(); \
+ if( bNoLoop ) \
+ pLayoutAccess->GetLayouter()->EndLoopControl(); \
+ return; \
+ } \
+ }
+#else
+#define CHECKPAGE \
+ { if ( IsAgain() ) \
+ return; \
+ }
+
+#define XCHECKPAGE \
+ { if ( IsAgain() ) \
+ { \
+ if( bNoLoop ) \
+ pLayoutAccess->GetLayouter()->EndLoopControl(); \
+ return; \
+ } \
+ }
+#endif
+
+#define RESCHEDULE \
+ { \
+ if ( IsReschedule() ) \
+ { \
+ if (pProgress) pProgress->Reschedule(); \
+ ::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \
+ } \
+ }
+
+inline ULONG Ticks()
+{
+ return 1000 * clock() / CLOCKS_PER_SEC;
+}
+
+void SwLayAction::CheckWaitCrsr()
+{
+ RESCHEDULE
+ if ( !IsWait() && IsWaitAllowed() && IsPaint() &&
+ ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC/2) )
+ {
+ pWait = new SwWait( *pRoot->GetFmt()->GetDoc()->GetDocShell(), TRUE );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::CheckIdleEnd()
+|*
+|* Ersterstellung MA 12. Aug. 94
+|* Letzte Aenderung MA 24. Jun. 96
+|*
+|*************************************************************************/
+//Ist es wirklich schon soweit...
+inline void SwLayAction::CheckIdleEnd()
+{
+ if ( !IsInput() )
+ bInput = GetInputType() && Application::AnyInput( GetInputType() );
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::SetStatBar()
+|*
+|* Ersterstellung MA 10. Aug. 94
+|* Letzte Aenderung MA 06. Aug. 95
+|*
+|*************************************************************************/
+void SwLayAction::SetStatBar( BOOL bNew )
+{
+ if ( bNew )
+ {
+ nEndPage = pRoot->GetPageNum();
+ nEndPage += nEndPage * 10 / 100;
+ }
+ else
+ nEndPage = USHRT_MAX;
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::PaintCntnt()
+|*
+|* Beschreibung Je nach Typ wird der Cntnt entsprechend seinen
+|* Veraenderungen ausgegeben bzw. wird die auszugebende Flaeche in der
+|* Region eingetragen.
+|* PaintCntnt: fuellt die Region,
+|* Ersterstellung BP 19. Jan. 92
+|* Letzte Aenderung MA 10. Sep. 96
+|*
+|*************************************************************************/
+BOOL SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt,
+ const SwPageFrm *pPage )
+{
+ SwRegionRects aTmp( rRect );
+ const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
+ const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm();
+ USHORT i;
+
+ for ( i = 0; i < rObjs.Count() && aTmp.Count(); ++i )
+ {
+ SdrObject *pO = rObjs[i]->DrawObj();
+ if ( !pO->ISA(SwVirtFlyDrawObj) )
+ continue;
+
+ // OD 2004-01-15 #110582# - do not consider invisible objects
+ const IDocumentDrawModelAccess* pIDDMA = pPage->GetFmt()->getIDocumentDrawModelAccess();
+ if ( !pIDDMA->IsVisibleLayerId( pO->GetLayer() ) )
+ {
+ continue;
+ }
+
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+
+ if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) )
+ continue;
+
+ if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
+ continue;
+
+ if ( pFly->GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() )
+ continue;
+
+ if ( pSelfFly )
+ {
+ const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
+ if ( pO->GetLayer() == pTmp->GetLayer() )
+ {
+ if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+ //Im gleichen Layer werden nur obenliegende beachtet.
+ continue;
+ }
+ else
+ {
+ const BOOL bLowerOfSelf = pFly->IsLowerOf( pSelfFly );
+ if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
+ //Aus anderem Layer interessieren uns nur nicht transparente
+ //oder innenliegende
+ continue;
+ }
+ }
+
+ /// OD 19.08.2002 #99657#
+ /// Fly frame without a lower have to be subtracted from paint region.
+ /// For checking, if fly frame contains transparent graphic or
+ /// has surrounded contour, assure that fly frame has a lower
+ if ( pFly->Lower() &&
+ pFly->Lower()->IsNoTxtFrm() &&
+ ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
+ pFly->GetFmt()->GetSurround().IsContour() )
+ )
+ {
+ continue;
+ }
+
+ /// OD 19.08.2002 #99657#
+ /// Region of a fly frame with transparent background or a transparent
+ /// shadow have not to be subtracted from paint region
+ if ( pFly->IsBackgroundTransparent() ||
+ pFly->IsShadowTransparent() )
+ {
+ continue;
+ }
+
+ aTmp -= pFly->Frm();
+ }
+
+ BOOL bRetPaint = FALSE;
+ const SwRect *pData = aTmp.GetData();
+ for ( i = 0; i < aTmp.Count(); ++pData, ++i )
+ bRetPaint |= pImp->GetShell()->AddPaintRect( *pData );
+ return bRetPaint;
+}
+
+inline BOOL SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt,
+ const SwPageFrm *pPage,
+ const SwRect &rRect )
+{
+ if ( rRect.HasArea() )
+ {
+ if ( pPage->GetSortedObjs() )
+ return PaintWithoutFlys( rRect, pCntnt, pPage );
+ else
+ return pImp->GetShell()->AddPaintRect( rRect );
+ }
+ return FALSE;
+}
+
+void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt,
+ const SwPageFrm *pPage,
+ const SwRect &rOldRect,
+ long nOldBottom )
+{
+ SWRECTFN( pCnt )
+
+ if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() )
+ {
+ SwRect aPaint( pCnt->PaintArea() );
+ if ( !_PaintCntnt( pCnt, pPage, aPaint ) )
+ pCnt->ResetCompletePaint();
+ }
+ else
+ {
+ // paint the area between printing bottom and frame bottom and
+ // the area left and right beside the frame, if its height changed.
+ long nOldHeight = (rOldRect.*fnRect->fnGetHeight)();
+ long nNewHeight = (pCnt->Frm().*fnRect->fnGetHeight)();
+ const bool bHeightDiff = nOldHeight != nNewHeight;
+ if( bHeightDiff )
+ {
+ // OD 05.11.2002 #94454# - consider whole potential paint area.
+ //SwRect aDrawRect( pCnt->UnionFrm( TRUE ) );
+ SwRect aDrawRect( pCnt->PaintArea() );
+ if( nOldHeight > nNewHeight )
+ nOldBottom = (pCnt->*fnRect->fnGetPrtBottom)();
+ (aDrawRect.*fnRect->fnSetTop)( nOldBottom );
+ _PaintCntnt( pCnt, pPage, aDrawRect );
+ }
+ // paint content area
+ SwRect aPaintRect = static_cast<SwTxtFrm*>(const_cast<SwCntntFrm*>(pCnt))->Paint();
+ _PaintCntnt( pCnt, pPage, aPaintRect );
+ }
+
+ if ( pCnt->IsRetouche() && !pCnt->GetNext() )
+ {
+ const SwFrm *pTmp = pCnt;
+ if( pCnt->IsInSct() )
+ {
+ const SwSectionFrm* pSct = pCnt->FindSctFrm();
+ if( pSct->IsRetouche() && !pSct->GetNext() )
+ pTmp = pSct;
+ }
+ SwRect aRect( pTmp->GetUpper()->PaintArea() );
+ (aRect.*fnRect->fnSetTop)( (pTmp->*fnRect->fnGetPrtBottom)() );
+ if ( !_PaintCntnt( pCnt, pPage, aRect ) )
+ pCnt->ResetRetouche();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::SwLayAction()
+|*
+|* Ersterstellung MA 30. Oct. 92
+|* Letzte Aenderung MA 09. Jun. 95
+|*
+|*************************************************************************/
+SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) :
+ pRoot( pRt ),
+ pImp( pI ),
+ pOptTab( 0 ),
+ pWait( 0 ),
+ pProgress(NULL),
+ nPreInvaPage( USHRT_MAX ),
+ nStartTicks( Ticks() ),
+ nInputType( 0 ),
+ nEndPage( USHRT_MAX ),
+ nCheckPageNum( USHRT_MAX )
+{
+ bPaintExtraData = ::IsExtraData( pImp->GetShell()->GetDoc() );
+ bPaint = bComplete = bWaitAllowed = bCheckPages = TRUE;
+ bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
+ bUpdateExpFlds = bBrowseActionStop = bActionInProgress = FALSE;
+ // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>.
+ mbFormatCntntOnInterrupt = sal_False;
+
+ pImp->pLayAct = this; //Anmelden
+}
+
+SwLayAction::~SwLayAction()
+{
+ ASSERT( !pWait, "Wait object not destroyed" );
+ pImp->pLayAct = 0; //Abmelden
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::Reset()
+|*
+|* Ersterstellung MA 11. Aug. 94
+|* Letzte Aenderung MA 09. Jun. 95
+|*
+|*************************************************************************/
+void SwLayAction::Reset()
+{
+ pOptTab = 0;
+ nStartTicks = Ticks();
+ nInputType = 0;
+ nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX;
+ bPaint = bComplete = bWaitAllowed = bCheckPages = TRUE;
+ bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
+ bUpdateExpFlds = bBrowseActionStop = FALSE;
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::RemoveEmptyBrowserPages()
+|*
+|* Ersterstellung MA 10. Sep. 97
+|* Letzte Aenderung MA 10. Sep. 97
+|*
+|*************************************************************************/
+
+BOOL SwLayAction::RemoveEmptyBrowserPages()
+{
+ //Beim umschalten vom normalen in den Browsermodus bleiben u.U. einige
+ //unangenehm lange stehen. Diese beseiten wir mal schnell.
+ BOOL bRet = FALSE;
+ if ( pRoot->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
+ do
+ {
+ if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) ||
+ pPage->ContainsCntnt() )
+ pPage = (SwPageFrm*)pPage->GetNext();
+ else
+ {
+ bRet = TRUE;
+ SwPageFrm *pDel = pPage;
+ pPage = (SwPageFrm*)pPage->GetNext();
+ pDel->Cut();
+ delete pDel;
+ }
+ } while ( pPage );
+ }
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|* SwLayAction::Action()
+|*
+|* Ersterstellung MA 10. Aug. 94
+|* Letzte Aenderung MA 06. Aug. 95
+|*
+|*************************************************************************/
+void SwLayAction::Action()
+{
+ bActionInProgress = TRUE;
+
+ //TurboMode? Disqualifiziert fuer Idle-Format.
+ if ( IsPaint() && !IsIdle() && TurboAction() )
+ {
+ delete pWait, pWait = 0;
+ pRoot->ResetTurboFlag();
+ bActionInProgress = FALSE;
+ pRoot->DeleteEmptySct();
+ return;
+ }
+ else if ( pRoot->GetTurbo() )
+ {
+ pRoot->DisallowTurbo();
+ const SwFrm *pFrm = pRoot->GetTurbo();
+ pRoot->ResetTurbo();
+ pFrm->InvalidatePage();
+ }
+ pRoot->DisallowTurbo();
+
+ if ( IsCalcLayout() )
+ SetCheckPages( FALSE );
+
+ InternalAction();
+ bAgain |= RemoveEmptyBrowserPages();
+ while ( IsAgain() )
+ {
+ bAgain = bNextCycle = FALSE;
+ InternalAction();
+ bAgain |= RemoveEmptyBrowserPages();
+ }
+ pRoot->DeleteEmptySct();
+
+ delete pWait, pWait = 0;
+
+ //Turbo-Action ist auf jedenfall wieder erlaubt.
+ pRoot->ResetTurboFlag();
+ pRoot->ResetTurbo();
+
+ SetCheckPages( TRUE );
+
+ bActionInProgress = FALSE;
+}
+
+SwPageFrm* SwLayAction::CheckFirstVisPage( SwPageFrm *pPage )
+{
+ SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt();
+ SwCntntFrm *pChk = pCnt;
+ BOOL bPageChgd = FALSE;
+ while ( pCnt && pCnt->IsFollow() )
+ pCnt = static_cast<SwCntntFrm*>(pCnt)->FindMaster();
+ if ( pCnt && pChk != pCnt )
+ { bPageChgd = TRUE;
+ pPage = pCnt->FindPageFrm();
+ }
+
+ if ( pPage->GetFmt()->GetDoc()->GetFtnIdxs().Count() )
+ {
+ SwFtnContFrm *pCont = pPage->FindFtnCont();
+ if ( pCont )
+ {
+ pCnt = pCont->ContainsCntnt();
+ pChk = pCnt;
+ while ( pCnt && pCnt->IsFollow() )
+ pCnt = (SwCntntFrm*)pCnt->FindPrev();
+ if ( pCnt && pCnt != pChk )
+ {
+ if ( bPageChgd )
+ {
+ //Die 'oberste' Seite benutzten.
+ SwPageFrm *pTmp = pCnt->FindPageFrm();
+ if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() )
+ pPage = pTmp;
+ }
+ else
+ pPage = pCnt->FindPageFrm();
+ }
+ }
+ }
+ return pPage;
+}
+
+// OD 2004-05-12 #i28701#
+// --> OD 2004-11-03 #i114798# - unlock position on start and end of page
+// layout process.
+class NotifyLayoutOfPageInProgress
+{
+ private:
+ SwPageFrm& mrPageFrm;
+
+ void _UnlockPositionOfObjs()
+ {
+ SwSortedObjs* pObjs = mrPageFrm.GetSortedObjs();
+ if ( pObjs )
+ {
+ sal_uInt32 i = 0;
+ for ( ; i < pObjs->Count(); ++i )
+ {
+ SwAnchoredObject* pObj = (*pObjs)[i];
+ pObj->UnlockPosition();
+ }
+ }
+ }
+ public:
+ NotifyLayoutOfPageInProgress( SwPageFrm& _rPageFrm )
+ : mrPageFrm( _rPageFrm )
+ {
+ _UnlockPositionOfObjs();
+ _rPageFrm.SetLayoutInProgress( true );
+ }
+ ~NotifyLayoutOfPageInProgress()
+ {
+ mrPageFrm.SetLayoutInProgress( false );
+ _UnlockPositionOfObjs();
+ }
+};
+// <--
+
+void SwLayAction::InternalAction()
+{
+ ASSERT( pRoot->Lower()->IsPageFrm(), ":-( Keine Seite unterhalb der Root.");
+
+ pRoot->Calc();
+
+ //Die erste ungueltige bzw. zu formatierende Seite ermitteln.
+ //Bei einer Complete-Action ist es die erste ungueltige; mithin ist die
+ //erste zu formatierende Seite diejenige Seite mit der Numemr eins.
+ //Bei einer Luegen-Formatierung ist die Nummer der erste Seite die Nummer
+ //der ersten Sichtbaren Seite.
+ SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() :
+ pImp->GetFirstVisPage();
+ if ( !pPage )
+ pPage = (SwPageFrm*)pRoot->Lower();
+
+ //Wenn ein "Erster-Fliess-Cntnt" innerhalb der der ersten sichtbaren Seite
+ //ein Follow ist, so schalten wir die Seite zurueck auf den Ur-Master dieses
+ //Cntnt's
+ if ( !IsComplete() )
+ pPage = CheckFirstVisPage( pPage );
+ USHORT nFirstPageNum = pPage->GetPhyPageNum();
+
+ while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
+ pPage = (SwPageFrm*)pPage->GetNext();
+
+ IDocumentLayoutAccess *pLayoutAccess = pRoot->GetFmt()->getIDocumentLayoutAccess();
+ BOOL bNoLoop = pPage ? SwLayouter::StartLoopControl( pRoot->GetFmt()->GetDoc(), pPage ) : FALSE;
+ USHORT nPercentPageNum = 0;
+ while ( (pPage && !IsInterrupt()) || nCheckPageNum != USHRT_MAX )
+ {
+ if ( !pPage && nCheckPageNum != USHRT_MAX &&
+ (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) )
+ {
+ if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum )
+ {
+ SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
+ while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum )
+ pPg = (SwPageFrm*)pPg->GetNext();
+ if ( pPg )
+ pPage = pPg;
+ if ( !pPage )
+ break;
+ }
+ SwPageFrm *pTmp = pPage->GetPrev() ?
+ (SwPageFrm*)pPage->GetPrev() : pPage;
+ SetCheckPages( TRUE );
+ SwFrm::CheckPageDescs( pPage );
+ SetCheckPages( FALSE );
+ nCheckPageNum = USHRT_MAX;
+ pPage = pTmp;
+ continue;
+ }
+
+ if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum )
+ {
+ nPercentPageNum = pPage->GetPhyPageNum();
+ ::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell());
+ }
+ pOptTab = 0;
+ //Kein ShortCut fuer Idle oder CalcLayout
+ if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) )
+ {
+ pRoot->DeleteEmptySct();
+ XCHECKPAGE;
+ if ( !IsInterrupt() &&
+ (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
+ {
+ if ( pRoot->IsAssertFlyPages() )
+ pRoot->AssertFlyPages();
+ if ( pRoot->IsSuperfluous() )
+ {
+ BOOL bOld = IsAgain();
+ pRoot->RemoveSuperfluous();
+ bAgain = bOld;
+ }
+ if ( IsAgain() )
+ {
+ if( bNoLoop )
+ pLayoutAccess->GetLayouter()->EndLoopControl();
+ return;
+ }
+ pPage = (SwPageFrm*)pRoot->Lower();
+ while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
+ pPage = (SwPageFrm*)pPage->GetNext();
+ while ( pPage && pPage->GetNext() &&
+ pPage->GetPhyPageNum() < nFirstPageNum )
+ pPage = (SwPageFrm*)pPage->GetNext();
+ continue;
+ }
+ break;
+ }
+ else
+ {
+ pRoot->DeleteEmptySct();
+ XCHECKPAGE;
+
+ // OD 2004-05-12 #i28701# - scope for instance of class
+ // <NotifyLayoutOfPageInProgress>
+ {
+ NotifyLayoutOfPageInProgress aLayoutOfPageInProgress( *pPage );
+
+ while ( !IsInterrupt() && !IsNextCycle() &&
+ ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) )
+ {
+ // OD 2004-05-10 #i28701#
+ SwObjectFormatter::FormatObjsAtFrm( *pPage, *pPage, this );
+ if ( !IS_FLYS )
+ {
+ //Wenn keine Flys (mehr) da sind, sind die Flags
+ //mehr als fluessig.
+ pPage->ValidateFlyLayout();
+ pPage->ValidateFlyCntnt();
+ }
+ // OD 2004-05-10 #i28701# - change condition
+ while ( !IsInterrupt() && !IsNextCycle() &&
+ ( pPage->IsInvalid() ||
+ (IS_FLYS && IS_INVAFLY) ) )
+ {
+ PROTOCOL( pPage, PROT_FILE_INIT, 0, 0)
+ XCHECKPAGE;
+
+ // FME 2007-08-30 #i81146# new loop control
+ USHORT nLoopControlRuns_1 = 0;
+ const USHORT nLoopControlMax = 20;
+
+ while ( !IsNextCycle() && pPage->IsInvalidLayout() )
+ {
+ pPage->ValidateLayout();
+
+ if ( ++nLoopControlRuns_1 > nLoopControlMax )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( false, "LoopControl_1 in SwLayAction::InternalAction" )
+#endif
+ break;
+ }
+
+ FormatLayout( pPage );
+ XCHECKPAGE;
+ }
+ // OD 2004-05-10 #i28701# - change condition
+ if ( !IsNextCycle() &&
+ ( pPage->IsInvalidCntnt() ||
+ (IS_FLYS && IS_INVAFLY) ) )
+ {
+ pPage->ValidateFlyInCnt();
+ pPage->ValidateCntnt();
+ // --> OD 2004-05-10 #i28701#
+ pPage->ValidateFlyLayout();
+ pPage->ValidateFlyCntnt();
+ // <--
+ if ( !FormatCntnt( pPage ) )
+ {
+ XCHECKPAGE;
+ pPage->InvalidateCntnt();
+ pPage->InvalidateFlyInCnt();
+ // --> OD 2004-05-10 #i28701#
+ pPage->InvalidateFlyLayout();
+ pPage->InvalidateFlyCntnt();
+ // <--
+ if ( IsBrowseActionStop() )
+ bInput = TRUE;
+ }
+ }
+ if( bNoLoop )
+ pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
+ }
+ }
+ } // end of scope for instance of class <NotifyLayoutOfPageInProgress>
+
+
+ //Eine vorige Seite kann wieder invalid sein.
+ XCHECKPAGE;
+ if ( !IS_FLYS )
+ {
+ //Wenn keine Flys (mehr) da sind, sind die Flags
+ //mehr als fluessig.
+ pPage->ValidateFlyLayout();
+ pPage->ValidateFlyCntnt();
+ }
+ if ( !IsInterrupt() )
+ {
+ SetNextCycle( FALSE );
+
+ if ( nPreInvaPage != USHRT_MAX )
+ {
+ if( !IsComplete() && nPreInvaPage + 2 < nFirstPageNum )
+ {
+ pImp->SetFirstVisPageInvalid();
+ SwPageFrm *pTmpPage = pImp->GetFirstVisPage();
+ nFirstPageNum = pTmpPage->GetPhyPageNum();
+ if( nPreInvaPage < nFirstPageNum )
+ {
+ nPreInvaPage = nFirstPageNum;
+ pPage = pTmpPage;
+ }
+ }
+ while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage )
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ nPreInvaPage = USHRT_MAX;
+ }
+
+ while ( pPage->GetPrev() &&
+ ( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() ||
+ ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() &&
+ ((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) &&
+ (((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >=
+ nFirstPageNum) )
+ {
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ }
+
+ //Weiter bis zur naechsten invaliden Seite.
+ while ( pPage && !pPage->IsInvalid() &&
+ (!IS_FLYS || !IS_INVAFLY) )
+ {
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+ if( bNoLoop )
+ pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
+ }
+ CheckIdleEnd();
+ }
+ if ( !pPage && !IsInterrupt() &&
+ (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
+ {
+ if ( pRoot->IsAssertFlyPages() )
+ pRoot->AssertFlyPages();
+ if ( pRoot->IsSuperfluous() )
+ {
+ BOOL bOld = IsAgain();
+ pRoot->RemoveSuperfluous();
+ bAgain = bOld;
+ }
+ if ( IsAgain() )
+ {
+ if( bNoLoop )
+ pLayoutAccess->GetLayouter()->EndLoopControl();
+ return;
+ }
+ pPage = (SwPageFrm*)pRoot->Lower();
+ while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
+ pPage = (SwPageFrm*)pPage->GetNext();
+ while ( pPage && pPage->GetNext() &&
+ pPage->GetPhyPageNum() < nFirstPageNum )
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+ }
+ if ( IsInterrupt() && pPage )
+ {
+ //Wenn ein Input anliegt wollen wir keinen Inhalt mehr Formatieren,
+ //Das Layout muessen wir aber schon in Ordnung bringen.
+ //Andernfalls kann folgende Situation auftreten (Bug: 3244):
+ //Am Ende des Absatz der letzten Seite wird Text eingegeben, so das
+ //der Absatz einen Follow fuer die nachste Seite erzeugt, ausserdem
+ //wird gleich schnell weitergetippt - Es liegt waehrend der
+ //Verarbeitung ein Input an. Der Absatz auf der neuen Seite wurde
+ //bereits anformatiert, die neue Seite ist Formatiert und steht
+ //auf CompletePaint, hat sich aber noch nicht im Auszugebenden Bereich
+ //eingetragen. Es wird gepaintet, das CompletePaint der Seite wird
+ //zurueckgesetzt weil der neue Absatz sich bereits eingetragen hatte,
+ //aber die Raender der Seite werden nicht gepaintet. Naja, bei der
+ //zwangslaeufig auftretenden naechsten LayAction traegt sich die Seite
+ //nicht mehr ein, weil ihre (LayoutFrm-)Flags bereits zurueckgesetzt
+ //wurden -- Der Rand der Seite wird nie gepaintet.
+ SwPageFrm *pPg = pPage;
+ XCHECKPAGE;
+ const SwRect &rVis = pImp->GetShell()->VisArea();
+
+ while( pPg && pPg->Frm().Bottom() < rVis.Top() )
+ pPg = (SwPageFrm*)pPg->GetNext();
+ if( pPg != pPage )
+ pPg = pPg ? (SwPageFrm*)pPg->GetPrev() : pPage;
+
+ // OD 14.04.2003 #106346# - set flag for interrupt content formatting
+ mbFormatCntntOnInterrupt = IsInput() && !IsStopPrt();
+ long nBottom = rVis.Bottom();
+ // --> OD 2005-02-15 #i42586# - format current page, if idle action is active
+ // This is an optimization for the case that the interrupt is created by
+ // the move of a form control object, which is represented by a window.
+ while ( pPg && ( pPg->Frm().Top() < nBottom ||
+ ( IsIdle() && pPg == pPage ) ) )
+ // <--
+ {
+ // --> OD 2004-10-11 #i26945# - follow-up of #i28701#
+ NotifyLayoutOfPageInProgress aLayoutOfPageInProgress( *pPg );
+
+ XCHECKPAGE;
+
+ // FME 2007-08-30 #i81146# new loop control
+ USHORT nLoopControlRuns_2 = 0;
+ const USHORT nLoopControlMax = 20;
+
+ // OD 14.04.2003 #106346# - special case: interrupt content formatting
+ // --> OD 2004-07-08 #i28701# - conditions, introduced by #106346#,
+ // are incorrect (marcos IS_FLYS and IS_INVAFLY only works for <pPage>)
+ // and are too strict.
+ // --> OD 2005-06-09 #i50432# - adjust interrupt formatting to
+ // normal page formatting - see above.
+ while ( ( mbFormatCntntOnInterrupt &&
+ ( pPg->IsInvalid() ||
+ ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) ||
+ ( !mbFormatCntntOnInterrupt && pPg->IsInvalidLayout() ) )
+ {
+ XCHECKPAGE;
+ // --> OD 2005-06-09 #i50432# - format also at-page anchored objects
+ SwObjectFormatter::FormatObjsAtFrm( *pPg, *pPg, this );
+ // <--
+ // --> OD 2005-06-09 #i50432#
+ if ( !pPg->GetSortedObjs() )
+ {
+ pPg->ValidateFlyLayout();
+ pPg->ValidateFlyCntnt();
+ }
+ // <--
+
+ // FME 2007-08-30 #i81146# new loop control
+ USHORT nLoopControlRuns_3 = 0;
+
+ while ( pPg->IsInvalidLayout() )
+ {
+ pPg->ValidateLayout();
+
+ if ( ++nLoopControlRuns_3 > nLoopControlMax )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( false, "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" )
+#endif
+ break;
+ }
+
+ FormatLayout( pPg );
+ XCHECKPAGE;
+ }
+
+ // --> OD 2005-06-09 #i50432#
+ if ( mbFormatCntntOnInterrupt &&
+ ( pPg->IsInvalidCntnt() ||
+ ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) )
+ // <--
+ {
+ pPg->ValidateFlyInCnt();
+ pPg->ValidateCntnt();
+ // --> OD 2004-05-10 #i26945# - follow-up of fix #117736#
+ pPg->ValidateFlyLayout();
+ pPg->ValidateFlyCntnt();
+ // <--
+
+ if ( ++nLoopControlRuns_2 > nLoopControlMax )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( false, "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" )
+#endif
+ break;
+ }
+
+ if ( !FormatCntnt( pPg ) )
+ {
+ XCHECKPAGE;
+ pPg->InvalidateCntnt();
+ pPg->InvalidateFlyInCnt();
+ // --> OD 2004-05-10 #i26945# - follow-up of fix #117736#
+ pPg->InvalidateFlyLayout();
+ pPg->InvalidateFlyCntnt();
+ // <--
+ }
+ // --> OD 2005-04-06 #i46807# - we are statisfied, if the
+ // content is formatted once complete.
+ else
+ {
+ break;
+ }
+ // <--
+ }
+ }
+ // <--
+ pPg = (SwPageFrm*)pPg->GetNext();
+ }
+ // OD 14.04.2003 #106346# - reset flag for special interrupt content formatting.
+ mbFormatCntntOnInterrupt = sal_False;
+ }
+ pOptTab = 0;
+ if( bNoLoop )
+ pLayoutAccess->GetLayouter()->EndLoopControl();
+}
+/*************************************************************************
+|*
+|* SwLayAction::TurboAction(), _TurboAction()
+|*
+|* Ersterstellung MA 04. Dec. 92
+|* Letzte Aenderung MA 15. Aug. 93
+|*
+|*************************************************************************/
+BOOL SwLayAction::_TurboAction( const SwCntntFrm *pCnt )
+{
+
+ const SwPageFrm *pPage = 0;
+ if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() )
+ {
+ const SwRect aOldRect( pCnt->UnionFrm( TRUE ) );
+ const long nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom();
+ pCnt->Calc();
+ if ( pCnt->Frm().Bottom() < aOldRect.Bottom() )
+ pCnt->SetRetouche();
+
+ pPage = pCnt->FindPageFrm();
+ PaintCntnt( pCnt, pPage, aOldRect, nOldBottom );
+
+ if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() )
+ {
+ const ULONG nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines();
+ ((SwTxtFrm*)pCnt)->RecalcAllLines();
+ if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() )
+ {
+ if ( IsPaintExtraData() )
+ pImp->GetShell()->AddPaintRect( pCnt->Frm() );
+ //Damit die restlichen LineNums auf der Seite bereichnet werden
+ //und nicht hier abgebrochen wird.
+ //Das im RecalcAllLines zu erledigen waere teuer, weil dort
+ //auch in unnoetigen Faellen (normale Action) auch immer die
+ //Seite benachrichtigt werden muesste.
+ const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
+ while ( pNxt &&
+ (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) )
+ pNxt = pNxt->GetNextCntntFrm();
+ if ( pNxt )
+ pNxt->InvalidatePage();
+ }
+ return FALSE;
+ }
+
+ if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) )
+ return FALSE;
+ }
+ if ( !pPage )
+ pPage = pCnt->FindPageFrm();
+
+ // OD 2004-05-10 #i28701# - format floating screen objects at content frame.
+ if ( pCnt->IsTxtFrm() &&
+ !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCnt)),
+ *pPage, this ) )
+ {
+ return FALSE;
+ }
+
+ if ( pPage->IsInvalidCntnt() )
+ return FALSE;
+ return TRUE;
+}
+
+BOOL SwLayAction::TurboAction()
+{
+ BOOL bRet = TRUE;
+
+ if ( pRoot->GetTurbo() )
+ {
+ if ( !_TurboAction( pRoot->GetTurbo() ) )
+ {
+ CheckIdleEnd();
+ bRet = FALSE;
+ }
+ pRoot->ResetTurbo();
+ }
+ else
+ bRet = FALSE;
+ return bRet;
+}
+/*************************************************************************
+|*
+|* SwLayAction::IsShortCut()
+|*
+|* Beschreibung: Liefert ein True, wenn die Seite vollstaendig unter
+|* oder rechts neben dem sichbaren Bereich liegt.
+|* Es kann passieren, dass sich die Verhaeltnisse derart aendern, dass
+|* die Verarbeitung (des Aufrufers!) mit der Vorgaengerseite der
+|* uebergebenen Seite weitergefuehrt werden muss. Der Paramter wird also
+|* ggf. veraendert!
+|* Fuer den BrowseMode kann auch dann der ShortCut aktiviert werden,
+|* wenn der ungueltige Inhalt der Seite unterhalb des sichbaren
+|* bereiches liegt.
+|* Ersterstellung MA 30. Oct. 92
+|* Letzte Aenderung MA 18. Jul. 96
+|*
+|*************************************************************************/
+const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom )
+{
+ ASSERT( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" );
+
+ if ( !pFrm->IsValid() || pFrm->IsCompletePaint() &&
+ pFrm->Frm().Top() < nBottom )
+ return pFrm;
+ pFrm = ((SwLayoutFrm*)pFrm)->Lower();
+ while ( pFrm )
+ {
+ if ( pFrm->IsLayoutFrm() )
+ {
+ if ( !pFrm->IsValid() || pFrm->IsCompletePaint() &&
+ pFrm->Frm().Top() < nBottom )
+ return pFrm;
+ const SwFrm *pTmp;
+ if ( 0 != (pTmp = ::lcl_FindFirstInvaLay( pFrm, nBottom )) )
+ return pTmp;
+ }
+ pFrm = pFrm->GetNext();
+ }
+ return 0;
+}
+
+const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom,
+ const SwCntntFrm *pFirst )
+{
+ const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() :
+ pLay->ContainsCntnt();
+ while ( pCnt )
+ {
+ if ( !pCnt->IsValid() || pCnt->IsCompletePaint() )
+ {
+ if ( pCnt->Frm().Top() <= nBottom )
+ return pCnt;
+ }
+
+ if ( pCnt->GetDrawObjs() )
+ {
+ const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
+ for ( USHORT i = 0; i < rObjs.Count(); ++i )
+ {
+ const SwAnchoredObject* pObj = rObjs[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
+ if ( pFly->IsFlyInCntFrm() )
+ {
+ if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() ||
+ pFly->IsCompletePaint() )
+ {
+ if ( pFly->Frm().Top() <= nBottom )
+ return pFly;
+ }
+ const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 );
+ if ( pFrm && pFrm->Frm().Bottom() <= nBottom )
+ return pFrm;
+ }
+ }
+ }
+ }
+ if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() )
+ return 0;
+ pCnt = pCnt->GetNextCntntFrm();
+ if ( !pLay->IsAnLower( pCnt ) )
+ break;
+ }
+ return 0;
+}
+
+// --> OD 2005-02-21 #i37877# - consider drawing objects
+const SwAnchoredObject* lcl_FindFirstInvaObj( const SwPageFrm* _pPage,
+ long _nBottom )
+{
+ ASSERT( _pPage->GetSortedObjs(), "FindFirstInvaObj, no Objs" )
+
+ for ( USHORT i = 0; i < _pPage->GetSortedObjs()->Count(); ++i )
+ {
+ const SwAnchoredObject* pObj = (*_pPage->GetSortedObjs())[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
+ if ( pFly->Frm().Top() <= _nBottom )
+ {
+ if ( pFly->IsInvalid() || pFly->IsCompletePaint() )
+ return pFly;
+
+ const SwFrm* pTmp;
+ if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, _nBottom, 0 )) &&
+ pTmp->Frm().Top() <= _nBottom )
+ return pFly;
+ }
+ }
+ else if ( pObj->ISA(SwAnchoredDrawObject) )
+ {
+ if ( !static_cast<const SwAnchoredDrawObject*>(pObj)->IsValidPos() )
+ {
+ return pObj;
+ }
+ }
+ }
+ return 0;
+}
+// <--
+
+BOOL SwLayAction::IsShortCut( SwPageFrm *&prPage )
+{
+ BOOL bRet = FALSE;
+ const BOOL bBrowse = pRoot->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE);
+
+ //Wenn die Seite nicht Gueltig ist wird sie schnell formatiert, sonst
+ //gibts nix als Aerger.
+ if ( !prPage->IsValid() )
+ {
+ if ( bBrowse )
+ {
+ /// OD 15.10.2002 #103517# - format complete page
+ /// Thus, loop on all lowers of the page <prPage>, instead of only
+ /// format its first lower.
+ /// NOTE: In online layout (bBrowse == TRUE) a page can contain
+ /// a header frame and/or a footer frame beside the body frame.
+ prPage->Calc();
+ SwFrm* pPageLowerFrm = prPage->Lower();
+ while ( pPageLowerFrm )
+ {
+ pPageLowerFrm->Calc();
+ pPageLowerFrm = pPageLowerFrm->GetNext();
+ }
+ }
+ else
+ FormatLayout( prPage );
+ if ( IsAgain() )
+ return FALSE;
+ }
+
+
+ const SwRect &rVis = pImp->GetShell()->VisArea();
+ if ( (prPage->Frm().Top() >= rVis.Bottom()) ||
+ (prPage->Frm().Left()>= rVis.Right()) )
+ {
+ bRet = TRUE;
+
+ //Jetzt wird es ein bischen unangenehm: Der erste CntntFrm dieser Seite
+ //im Bodytext muss Formatiert werden, wenn er dabei die Seite
+ //wechselt, muss ich nochmal eine Seite zuvor anfangen, denn
+ //es wurde ein PageBreak verarbeitet.
+//Noch unangenehmer: Der naechste CntntFrm ueberhaupt muss
+ //Formatiert werden, denn es kann passieren, dass kurzfristig
+ //leere Seiten existieren (Bsp. Absatz ueber mehrere Seiten
+ //wird geloescht oder verkleinert).
+
+ //Ist fuer den Browser uninteressant, wenn der letzte Cnt davor bereits
+ //nicht mehr sichbar ist.
+
+ const SwPageFrm *p2ndPage = prPage;
+ const SwCntntFrm *pCntnt;
+ const SwLayoutFrm* pBody = p2ndPage->FindBodyCont();
+ if( p2ndPage->IsFtnPage() && pBody )
+ pBody = (SwLayoutFrm*)pBody->GetNext();
+ pCntnt = pBody ? pBody->ContainsCntnt() : 0;
+ while ( p2ndPage && !pCntnt )
+ {
+ p2ndPage = (SwPageFrm*)p2ndPage->GetNext();
+ if( p2ndPage )
+ {
+ pBody = p2ndPage->FindBodyCont();
+ if( p2ndPage->IsFtnPage() && pBody )
+ pBody = (SwLayoutFrm*)pBody->GetNext();
+ pCntnt = pBody ? pBody->ContainsCntnt() : 0;
+ }
+ }
+ if ( pCntnt )
+ {
+ BOOL bTstCnt = TRUE;
+ if ( bBrowse )
+ {
+ //Der Cnt davor schon nicht mehr sichtbar?
+ const SwFrm *pLst = pCntnt;
+ if ( pLst->IsInTab() )
+ pLst = pCntnt->FindTabFrm();
+ if ( pLst->IsInSct() )
+ pLst = pCntnt->FindSctFrm();
+ pLst = pLst->FindPrev();
+ if ( pLst &&
+ (pLst->Frm().Top() >= rVis.Bottom() ||
+ pLst->Frm().Left()>= rVis.Right()) )
+ {
+ bTstCnt = FALSE;
+ }
+ }
+
+ if ( bTstCnt )
+ {
+ // --> OD 2004-06-04 #i27756# - check after each frame calculation,
+ // if the content frame has changed the page. If yes, no other
+ // frame calculation is performed
+ bool bPageChg = false;
+
+ if ( pCntnt->IsInSct() )
+ {
+ const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
+ if ( !pSct->IsValid() )
+ {
+ pSct->Calc();
+ pSct->SetCompletePaint();
+ if ( IsAgain() )
+ return FALSE;
+ // --> OD 2004-06-04 #i27756#
+ bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
+ prPage->GetPrev();
+ }
+ }
+
+ if ( !bPageChg && !pCntnt->IsValid() )
+ {
+ pCntnt->Calc();
+ pCntnt->SetCompletePaint();
+ if ( IsAgain() )
+ return FALSE;
+ // --> OD 2004-06-04 #i27756#
+ bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
+ prPage->GetPrev();
+ }
+
+ if ( !bPageChg && pCntnt->IsInTab() )
+ {
+ const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm();
+ if ( !pTab->IsValid() )
+ {
+ pTab->Calc();
+ pTab->SetCompletePaint();
+ if ( IsAgain() )
+ return FALSE;
+ // --> OD 2004-06-04 #i27756#
+ bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
+ prPage->GetPrev();
+ }
+ }
+
+ if ( !bPageChg && pCntnt->IsInSct() )
+ {
+ const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
+ if ( !pSct->IsValid() )
+ {
+ pSct->Calc();
+ pSct->SetCompletePaint();
+ if ( IsAgain() )
+ return FALSE;
+ // --> OD 2004-06-04 #i27756#
+ bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
+ prPage->GetPrev();
+ }
+ }
+
+ // --> OD 2004-06-04 #i27756#
+ if ( bPageChg )
+ {
+ bRet = FALSE;
+ const SwPageFrm* pTmp = pCntnt->FindPageFrm();
+ if ( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() &&
+ pTmp->IsInvalid() )
+ {
+ prPage = (SwPageFrm*)pTmp;
+ }
+ else
+ {
+ prPage = (SwPageFrm*)prPage->GetPrev();
+ }
+ }
+ // --> OD 2005-04-25 #121980# - no shortcut, if at previous page
+ // an anchored object is registered, whose anchor is <pCntnt>.
+ else if ( prPage->GetPrev() &&
+ static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs() )
+ {
+ SwSortedObjs* pObjs =
+ static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs();
+ if ( pObjs )
+ {
+ sal_uInt32 i = 0;
+ for ( ; i < pObjs->Count(); ++i )
+ {
+ SwAnchoredObject* pObj = (*pObjs)[i];
+ if ( pObj->GetAnchorFrmContainingAnchPos() == pCntnt )
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ // <--
+ }
+ }
+ }
+
+ if ( !bRet && bBrowse )
+ {
+ const long nBottom = rVis.Bottom();
+ const SwAnchoredObject* pObj( 0L );
+ if ( prPage->GetSortedObjs() &&
+ (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) &&
+ 0 != (pObj = lcl_FindFirstInvaObj( prPage, nBottom )) &&
+ pObj->GetObjRect().Top() <= nBottom )
+ {
+ return FALSE;
+ }
+ const SwFrm* pFrm( 0L );
+ if ( prPage->IsInvalidLayout() &&
+ 0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) &&
+ pFrm->Frm().Top() <= nBottom )
+ {
+ return FALSE;
+ }
+ if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) &&
+ 0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) &&
+ pFrm->Frm().Top() <= nBottom )
+ {
+ return FALSE;
+ }
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab()
+|*
+|* Ersterstellung MA 30. Oct. 92
+|* Letzte Aenderung MA 18. May. 98
+|*
+|*************************************************************************/
+// OD 15.11.2002 #105155# - introduce support for vertical layout
+BOOL SwLayAction::FormatLayout( SwLayoutFrm *pLay, BOOL bAddRect )
+{
+ ASSERT( !IsAgain(), "Ungueltige Seite beachten." );
+ if ( IsAgain() )
+ return FALSE;
+
+ BOOL bChanged = FALSE;
+ BOOL bAlreadyPainted = FALSE;
+ // OD 11.11.2002 #104414# - remember frame at complete paint
+ SwRect aFrmAtCompletePaint;
+
+ if ( !pLay->IsValid() || pLay->IsCompletePaint() )
+ {
+ if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() )
+ pLay->GetPrev()->SetCompletePaint();
+
+ SwRect aOldRect( pLay->Frm() );
+ pLay->Calc();
+ if ( aOldRect != pLay->Frm() )
+ bChanged = TRUE;
+
+ BOOL bNoPaint = FALSE;
+ if ( pLay->IsPageBodyFrm() &&
+ pLay->Frm().Pos() == aOldRect.Pos() &&
+ pLay->Lower() &&
+ pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ //HotFix: Vobis Homepage, nicht so genau hinsehen, sonst
+ //rpaints
+
+ //Einschraenkungen wegen Kopf-/Fusszeilen
+ if ( !( pLay->IsCompletePaint() &&
+ pLay->FindPageFrm()->FindFtnCont() ) )
+ {
+ bNoPaint = TRUE;
+ }
+ }
+
+ if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) )
+ {
+ SwRect aPaint( pLay->Frm() );
+ // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for
+ // page frames -> enlarge paint rectangle correspondingly.
+ if ( pLay->IsPageFrm() )
+ {
+ SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay);
+ const int nBorderWidth =
+ pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->BorderPxWidth(), 0 ) ).Width();
+ const int nShadowWidth =
+ pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->ShadowPxWidth(), 0 ) ).Width();
+
+ //mod #i6193# added sidebar width
+ const SwPostItMgr* pPostItMgr = pImp->GetShell()->GetPostItMgr();
+ const int nSidebarWidth = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
+ switch ( pPageFrm->SidebarPosition() )
+ {
+ case sw::sidebarwindows::SIDEBAR_LEFT:
+ {
+ aPaint.Left( aPaint.Left() - nBorderWidth - nSidebarWidth);
+ aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth);
+ }
+ break;
+ case sw::sidebarwindows::SIDEBAR_RIGHT:
+ {
+ aPaint.Left( aPaint.Left() - nBorderWidth );
+ aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth + nSidebarWidth);
+ }
+ break;
+ case sw::sidebarwindows::SIDEBAR_NONE:
+ // nothing to do
+ break;
+ }
+ aPaint.Top( aPaint.Top() - nBorderWidth );
+ aPaint.Bottom( aPaint.Bottom() + nBorderWidth + nShadowWidth);
+ }
+
+ if ( pLay->IsPageFrm() &&
+ pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ // NOTE: no vertical layout in online layout
+ //Ist die Aenderung ueberhaupt sichtbar?
+ if ( pLay->IsCompletePaint() )
+ {
+ pImp->GetShell()->AddPaintRect( aPaint );
+ bAddRect = FALSE;
+ }
+ else
+ {
+ USHORT i;
+
+ SwRegionRects aRegion( aOldRect );
+ aRegion -= aPaint;
+ for ( i = 0; i < aRegion.Count(); ++i )
+ pImp->GetShell()->AddPaintRect( aRegion[i] );
+ aRegion.ChangeOrigin( aPaint );
+ aRegion.Remove( 0, aRegion.Count() );
+ aRegion.Insert( aPaint, 0 );
+ aRegion -= aOldRect;
+ for ( i = 0; i < aRegion.Count(); ++i )
+ pImp->GetShell()->AddPaintRect( aRegion[i] );
+ }
+
+ }
+ else
+ {
+ pImp->GetShell()->AddPaintRect( aPaint );
+ bAlreadyPainted = TRUE;
+ // OD 11.11.2002 #104414# - remember frame at complete paint
+ aFrmAtCompletePaint = pLay->Frm();
+ }
+
+ // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing
+ // between pages (not only for in online mode).
+ if ( pLay->IsPageFrm() )
+ {
+ const SwTwips nHalfDocBorder = GAPBETWEENPAGES;
+ const bool bLeftToRightViewLayout = pRoot->IsLeftToRightViewLayout();
+ const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext();
+ const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev();
+
+ if ( bPrev )
+ {
+ // top
+ SwRect aSpaceToPrevPage( pLay->Frm() );
+ const SwTwips nTop = aSpaceToPrevPage.Top() - nHalfDocBorder;
+ if ( nTop >= 0 )
+ aSpaceToPrevPage.Top( nTop );
+ aSpaceToPrevPage.Bottom( pLay->Frm().Top() );
+ pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
+
+ // left
+ aSpaceToPrevPage = pLay->Frm();
+ const SwTwips nLeft = aSpaceToPrevPage.Left() - nHalfDocBorder;
+ if ( nLeft >= 0 )
+ aSpaceToPrevPage.Left( nLeft );
+ aSpaceToPrevPage.Right( pLay->Frm().Left() );
+ pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
+ }
+ if ( bNext )
+ {
+ // bottom
+ SwRect aSpaceToNextPage( pLay->Frm() );
+ aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder );
+ aSpaceToNextPage.Top( pLay->Frm().Bottom() );
+ pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
+
+ // right
+ aSpaceToNextPage = pLay->Frm();
+ aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder );
+ aSpaceToNextPage.Left( pLay->Frm().Right() );
+ pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
+ }
+ }
+ }
+ pLay->ResetCompletePaint();
+ }
+
+ if ( IsPaint() && bAddRect &&
+ !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() )
+ {
+ // OD 15.11.2002 #105155# - vertical layout support
+ SWRECTFN( pLay );
+ SwRect aRect( pLay->GetUpper()->PaintArea() );
+ (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() );
+ if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+ pLay->ResetRetouche();
+ }
+
+ if( bAlreadyPainted )
+ bAddRect = FALSE;
+
+ CheckWaitCrsr();
+
+ if ( IsAgain() )
+ return FALSE;
+
+ //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind
+
+ if ( pLay->IsFtnFrm() ) //Hat keine LayFrms als Lower.
+ return bChanged;
+
+ SwFrm *pLow = pLay->Lower();
+ BOOL bTabChanged = FALSE;
+ while ( pLow && pLow->GetUpper() == pLay )
+ {
+ if ( pLow->IsLayoutFrm() )
+ {
+ if ( pLow->IsTabFrm() )
+ bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
+ // bereits zum Loeschen angemeldete Ueberspringen
+ else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() )
+ bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
+ }
+ else if ( pImp->GetShell()->IsPaintLocked() )
+ //Abkuerzung im die Zyklen zu minimieren, bei Lock kommt das
+ //Paint sowieso (Primaer fuer Browse)
+ pLow->OptCalc();
+
+ if ( IsAgain() )
+ return FALSE;
+ pLow = pLow->GetNext();
+ }
+ // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame
+ // area has been already added and after formating its lowers the frame area
+ // is enlarged.
+ if ( bAlreadyPainted &&
+ ( pLay->Frm().Width() > aFrmAtCompletePaint.Width() ||
+ pLay->Frm().Height() > aFrmAtCompletePaint.Height() )
+ )
+ {
+ pImp->GetShell()->AddPaintRect( pLay->Frm() );
+ }
+ return bChanged || bTabChanged;
+}
+
+BOOL SwLayAction::FormatLayoutFly( SwFlyFrm* pFly )
+{
+ ASSERT( !IsAgain(), "Ungueltige Seite beachten." );
+ if ( IsAgain() )
+ return FALSE;
+
+ BOOL bChanged = false;
+ BOOL bAddRect = true;
+
+ if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() )
+ {
+ //Der Frame hat sich veraendert, er wird jetzt Formatiert
+ const SwRect aOldRect( pFly->Frm() );
+ pFly->Calc();
+ bChanged = aOldRect != pFly->Frm();
+
+ if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) &&
+ pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
+ pImp->GetShell()->AddPaintRect( pFly->Frm() );
+
+ if ( bChanged )
+ pFly->Invalidate();
+ else
+ pFly->Validate();
+ bAddRect = false;
+ pFly->ResetCompletePaint();
+ }
+
+ if ( IsAgain() )
+ return FALSE;
+
+ //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind
+ BOOL bTabChanged = false;
+ SwFrm *pLow = pFly->Lower();
+ while ( pLow )
+ {
+ if ( pLow->IsLayoutFrm() )
+ {
+ if ( pLow->IsTabFrm() )
+ bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
+ else
+ bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
+ }
+ pLow = pLow->GetNext();
+ }
+ return bChanged || bTabChanged;
+}
+
+// OD 31.10.2002 #104100#
+// Implement vertical layout support
+BOOL SwLayAction::FormatLayoutTab( SwTabFrm *pTab, BOOL bAddRect )
+{
+ ASSERT( !IsAgain(), "8-) Ungueltige Seite beachten." );
+ if ( IsAgain() || !pTab->Lower() )
+ return FALSE;
+
+ IDocumentTimerAccess *pTimerAccess = pRoot->GetFmt()->getIDocumentTimerAccess();
+ pTimerAccess->BlockIdling();
+
+ BOOL bChanged = FALSE;
+ BOOL bPainted = FALSE;
+
+ const SwPageFrm *pOldPage = pTab->FindPageFrm();
+
+ // OD 31.10.2002 #104100# - vertical layout support
+ // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and
+ // <SwRectFn fnRect> for table frame <pTab>.
+ SWRECTFN( pTab );
+
+ if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() )
+ {
+ if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() )
+ {
+ pTab->GetPrev()->SetCompletePaint();
+ }
+
+ const SwRect aOldRect( pTab->Frm() );
+ pTab->SetLowersFormatted( FALSE );
+ pTab->Calc();
+ if ( aOldRect != pTab->Frm() )
+ {
+ bChanged = TRUE;
+ }
+ const SwRect aPaintFrm = pTab->PaintArea();
+
+ if ( IsPaint() && bAddRect )
+ {
+ // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()>
+ if ( !pTab->IsCompletePaint() &&
+ pTab->IsComplete() &&
+ ( pTab->Frm().SSize() != pTab->Prt().SSize() ||
+ // OD 31.10.2002 #104100# - vertical layout support
+ (pTab->*fnRect->fnGetLeftMargin)() ) &&
+ pTab->Frm().HasArea()
+ )
+ {
+ // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles.
+ SwRect aMarginRect;
+
+ SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)();
+ if ( nLeftMargin > 0)
+ {
+ aMarginRect = pTab->Frm();
+ (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin );
+ pImp->GetShell()->AddPaintRect( aMarginRect );
+ }
+
+ if ( (pTab->*fnRect->fnGetRightMargin)() > 0)
+ {
+ aMarginRect = pTab->Frm();
+ (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() );
+ pImp->GetShell()->AddPaintRect( aMarginRect );
+ }
+
+ SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)();
+ if ( nTopMargin > 0)
+ {
+ aMarginRect = pTab->Frm();
+ (aMarginRect.*fnRect->fnSetHeight)( nTopMargin );
+ pImp->GetShell()->AddPaintRect( aMarginRect );
+ }
+
+ if ( (pTab->*fnRect->fnGetBottomMargin)() > 0)
+ {
+ aMarginRect = pTab->Frm();
+ (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
+ pImp->GetShell()->AddPaintRect( aMarginRect );
+ }
+ }
+ else if ( pTab->IsCompletePaint() )
+ {
+ pImp->GetShell()->AddPaintRect( aPaintFrm );
+ bAddRect = FALSE;
+ bPainted = TRUE;
+ }
+
+ if ( pTab->IsRetouche() && !pTab->GetNext() )
+ {
+ SwRect aRect( pTab->GetUpper()->PaintArea() );
+ // OD 04.11.2002 #104100# - vertical layout support
+ (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
+ if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+ pTab->ResetRetouche();
+ }
+ }
+ else
+ bAddRect = FALSE;
+
+ if ( pTab->IsCompletePaint() && !pOptTab )
+ pOptTab = pTab;
+ pTab->ResetCompletePaint();
+ }
+ if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() )
+ {
+ // OD 04.10.2002 #102779#
+ // set correct rectangle for retouche: area between bottom of table frame
+ // and bottom of paint area of the upper frame.
+ SwRect aRect( pTab->GetUpper()->PaintArea() );
+ // OD 04.11.2002 #104100# - vertical layout support
+ (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
+ if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+ pTab->ResetRetouche();
+ }
+
+ CheckWaitCrsr();
+
+ pTimerAccess->UnblockIdling();
+
+ //Heftige Abkuerzung!
+ if ( pTab->IsLowersFormatted() &&
+ (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) )
+ return FALSE;
+
+ //Jetzt noch die Lowers versorgen
+ if ( IsAgain() )
+ return FALSE;
+
+ // OD 20.10.2003 #112464# - for savety reasons:
+ // check page number before formatting lowers.
+ if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) )
+ SetNextCycle( TRUE );
+
+ // OD 20.10.2003 #112464# - format lowers, only if table frame is valid
+ if ( pTab->IsValid() )
+ {
+ SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower();
+ while ( pLow )
+ {
+ bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
+ if ( IsAgain() )
+ return FALSE;
+ pLow = (SwLayoutFrm*)pLow->GetNext();
+ }
+ }
+
+ return bChanged;
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::FormatCntnt()
+|*
+|* Ersterstellung MA 30. Oct. 92
+|* Letzte Aenderung MA 16. Nov. 95
+|*
+|*************************************************************************/
+BOOL SwLayAction::FormatCntnt( const SwPageFrm *pPage )
+{
+ const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
+ const BOOL bBrowse = pRoot->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE);
+
+ while ( pCntnt && pPage->IsAnLower( pCntnt ) )
+ {
+ //Wenn der Cntnt sich eh nicht veraendert koennen wir ein paar
+ //Abkuerzungen nutzen.
+ const BOOL bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() ||
+ pCntnt->IsRetouche() || pCntnt->GetDrawObjs();
+ if ( bFull )
+ {
+ //Damit wir nacher nicht suchen muessen.
+ const BOOL bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow();
+ const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0;
+ const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0;
+
+ const SwLayoutFrm*pOldUpper = pCntnt->GetUpper();
+ const SwTabFrm *pTab = pCntnt->FindTabFrm();
+ const BOOL bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint();
+ const BOOL bOldPaint = IsPaint();
+ bPaint = bOldPaint && !(pTab && pTab == pOptTab);
+ _FormatCntnt( pCntnt, pPage );
+ // --> OD 2004-11-05 #i26945# - reset <bPaint> before format objects
+ bPaint = bOldPaint;
+ // <--
+
+ // OD 2004-05-10 #i28701# - format floating screen object at content frame.
+ // No format, if action flag <bAgain> is set or action is interrupted.
+ // OD 2004-08-30 #117736# - allow format on interruption of action, if
+ // it's the format for this interrupt
+ // --> OD 2004-11-01 #i23129#, #i36347# - pass correct page frame
+ // to the object formatter.
+ if ( !IsAgain() &&
+ ( !IsInterrupt() || mbFormatCntntOnInterrupt ) &&
+ pCntnt->IsTxtFrm() &&
+ !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCntnt)),
+ *(pCntnt->FindPageFrm()), this ) )
+ // <--
+ {
+ return FALSE;
+ }
+
+ if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
+ {
+ const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
+ ((SwTxtFrm*)pCntnt)->RecalcAllLines();
+ if ( IsPaintExtraData() && IsPaint() &&
+ nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
+ pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
+ }
+
+ if ( IsAgain() )
+ return FALSE;
+
+ //Wenn Layout oder Flys wieder Invalid sind breche ich die Verarbeitung
+ //vorlaeufig ab - allerdings nicht fuer die BrowseView, denn dort wird
+ //das Layout staendig ungueltig, weil die Seitenhoehe angepasst wird.
+ //Desgleichen wenn der Benutzer weiterarbeiten will und mindestens ein
+ //Absatz verarbeitet wurde.
+ if ( (!pTab || (pTab && !bInValid)) )
+ {
+ CheckIdleEnd();
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) ||
+ ( !bBrowse && pPage->IsInvalidLayout() ) ||
+ // OD 07.05.2003 #109435# - consider interrupt formatting
+ ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt )
+ )
+ return FALSE;
+ }
+ if ( pOldUpper != pCntnt->GetUpper() )
+ {
+ const USHORT nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum();
+ if ( nCurNum < pPage->GetPhyPageNum() )
+ nPreInvaPage = nCurNum;
+
+ //Wenn der Frm mehr als eine Seite rueckwaerts geflossen ist, so
+ //fangen wir nocheinmal von vorn an damit wir nichts auslassen.
+ if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 )
+ {
+ SetNextCycle( TRUE );
+ // OD 07.05.2003 #109435# - consider interrupt formatting
+ if ( !mbFormatCntntOnInterrupt )
+ {
+ return FALSE;
+ }
+ }
+ }
+ //Wenn der Frame die Seite vorwaerts gewechselt hat, so lassen wir
+ //den Vorgaenger nocheinmal durchlaufen.
+ //So werden einerseits Vorgaenger erwischt, die jetzt f?r Retouche
+ //verantwortlich sind, andererseits werden die Fusszeilen
+ //auch angefasst.
+ BOOL bSetCntnt = TRUE;
+ if ( pCntntPrev )
+ {
+ if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) )
+ pPage->InvalidateCntnt();
+ if ( pOldUpper != pCntnt->GetUpper() &&
+ pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() )
+ {
+ pCntnt = pCntntPrev;
+ bSetCntnt = FALSE;
+ }
+ }
+ if ( bSetCntnt )
+ {
+ if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
+ pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
+ {
+ const long nBottom = pImp->GetShell()->VisArea().Bottom();
+ const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
+ nBottom, pCntnt );
+ if ( !pTmp )
+ {
+ if ( (!(IS_FLYS && IS_INVAFLY) ||
+ !lcl_FindFirstInvaObj( pPage, nBottom )) &&
+ (!pPage->IsInvalidLayout() ||
+ !lcl_FindFirstInvaLay( pPage, nBottom )))
+ SetBrowseActionStop( TRUE );
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ if ( !mbFormatCntntOnInterrupt )
+ {
+ return FALSE;
+ }
+ }
+ }
+ pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm();
+ }
+
+ RESCHEDULE;
+ }
+ else
+ {
+ if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
+ {
+ const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
+ ((SwTxtFrm*)pCntnt)->RecalcAllLines();
+ if ( IsPaintExtraData() && IsPaint() &&
+ nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
+ pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
+ }
+
+ //Falls der Frm schon vor der Abarbeitung hier formatiert wurde.
+ if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() &&
+ IsPaint() )
+ PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom());
+ if ( IsIdle() )
+ {
+ CheckIdleEnd();
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
+ return FALSE;
+ }
+ if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
+ pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
+ {
+ const long nBottom = pImp->GetShell()->VisArea().Bottom();
+ const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
+ nBottom, pCntnt );
+ if ( !pTmp )
+ {
+ if ( (!(IS_FLYS && IS_INVAFLY) ||
+ !lcl_FindFirstInvaObj( pPage, nBottom )) &&
+ (!pPage->IsInvalidLayout() ||
+ !lcl_FindFirstInvaLay( pPage, nBottom )))
+ SetBrowseActionStop( TRUE );
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ if ( !mbFormatCntntOnInterrupt )
+ {
+ return FALSE;
+ }
+ }
+ }
+ pCntnt = pCntnt->GetNextCntntFrm();
+ }
+ }
+ CheckWaitCrsr();
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ return !IsInterrupt() || mbFormatCntntOnInterrupt;
+}
+/*************************************************************************
+|*
+|* SwLayAction::_FormatCntnt()
+|*
+|* Beschreibung Returnt TRUE wenn der Absatz verarbeitet wurde,
+|* FALSE wenn es nichts zu verarbeiten gab.
+|* Ersterstellung MA 07. Dec. 92
+|* Letzte Aenderung MA 11. Mar. 98
+|*
+|*************************************************************************/
+void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt,
+ const SwPageFrm *pPage )
+{
+ //wird sind hier evtl. nur angekommen, weil der Cntnt DrawObjekte haelt.
+ const BOOL bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() &&
+ !pCntnt->IsRetouche();
+ SWRECTFN( pCntnt )
+ if ( !bDrawObjsOnly && IsPaint() )
+ {
+ const SwRect aOldRect( pCntnt->UnionFrm() );
+ const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)();
+ pCntnt->OptCalc();
+ if( IsAgain() )
+ return;
+ if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(),
+ (aOldRect.*fnRect->fnGetBottom)() ) < 0 )
+ {
+ pCntnt->SetRetouche();
+ }
+ PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom);
+ }
+ else
+ {
+ if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() )
+ PaintCntnt( pCntnt, pPage, pCntnt->Frm(),
+ (pCntnt->Frm().*fnRect->fnGetBottom)() );
+ pCntnt->OptCalc();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::_FormatFlyCntnt()
+|*
+|* Beschreibung:
+|* - Returnt TRUE wenn alle Cntnts des Flys vollstaendig verarbeitet
+|* wurden. FALSE wenn vorzeitig unterbrochen wurde.
+|* Ersterstellung MA 02. Dec. 92
+|* Letzte Aenderung MA 24. Jun. 96
+|*
+|*************************************************************************/
+BOOL SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly )
+{
+ const SwCntntFrm *pCntnt = pFly->ContainsCntnt();
+
+ while ( pCntnt )
+ {
+ // OD 2004-05-10 #i28701#
+ _FormatCntnt( pCntnt, pCntnt->FindPageFrm() );
+
+ // --> OD 2004-07-23 #i28701# - format floating screen objects
+ // at content text frame
+ // --> OD 2004-11-02 #i23129#, #i36347# - pass correct page frame
+ // to the object formatter.
+ if ( pCntnt->IsTxtFrm() &&
+ !SwObjectFormatter::FormatObjsAtFrm(
+ *(const_cast<SwCntntFrm*>(pCntnt)),
+ *(pCntnt->FindPageFrm()), this ) )
+ // <--
+ {
+ // restart format with first content
+ pCntnt = pFly->ContainsCntnt();
+ continue;
+ }
+ // <--
+
+ if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
+ {
+ const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
+ ((SwTxtFrm*)pCntnt)->RecalcAllLines();
+ if ( IsPaintExtraData() && IsPaint() &&
+ nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
+ pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
+ }
+
+ if ( IsAgain() )
+ return FALSE;
+
+ //wenn eine Eingabe anliegt breche ich die Verarbeitung ab.
+ if ( !pFly->IsFlyInCntFrm() )
+ {
+ CheckIdleEnd();
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
+ return FALSE;
+ }
+ pCntnt = pCntnt->GetNextCntntFrm();
+ }
+ CheckWaitCrsr();
+ // OD 14.04.2003 #106346# - consider interrupt formatting.
+ return !(IsInterrupt() && !mbFormatCntntOnInterrupt);
+}
+
+BOOL SwLayAction::IsStopPrt() const
+{
+ BOOL bResult = FALSE;
+
+ if (pImp != NULL && pProgress != NULL)
+ bResult = pImp->IsStopPrt();
+
+ return bResult;
+}
+
+/*************************************************************************
+|*
+|* SwLayAction::FormatSpelling(), _FormatSpelling()
+|*
+|* Ersterstellung AMA 01. Feb. 96
+|* Letzte Aenderung AMA 01. Feb. 96
+|*
+|*************************************************************************/
+BOOL SwLayIdle::_DoIdleJob( const SwCntntFrm *pCnt, IdleJobType eJob )
+{
+ ASSERT( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" );
+ // robust against misuse by e.g. #i52542#
+ if( !pCnt->IsTxtFrm() )
+ return FALSE;
+
+ const SwTxtNode* pTxtNode = pCnt->GetNode()->GetTxtNode();
+
+ bool bProcess = false;
+ switch ( eJob )
+ {
+ case ONLINE_SPELLING :
+ bProcess = pTxtNode->IsWrongDirty(); break;
+ case AUTOCOMPLETE_WORDS :
+ bProcess = pTxtNode->IsAutoCompleteWordDirty(); break;
+ case WORD_COUNT :
+ bProcess = pTxtNode->IsWordCountDirty(); break;
+ case SMART_TAGS : // SMARTTAGS
+ bProcess = pTxtNode->IsSmartTagDirty(); break;
+ }
+
+ if( bProcess )
+ {
+ ViewShell *pSh = pImp->GetShell();
+ if( STRING_LEN == nTxtPos )
+ {
+ --nTxtPos;
+ if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() )
+ {
+ SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr();
+ if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() )
+ {
+ pCntntNode = pCrsr->GetCntntNode();
+ nTxtPos = pCrsr->GetPoint()->nContent.GetIndex();
+ }
+ }
+ }
+
+ switch ( eJob )
+ {
+ case ONLINE_SPELLING :
+ {
+ SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode, *pSh->GetViewOptions(), nTxtPos ) );
+ bPageValid = bPageValid && !pTxtNode->IsWrongDirty();
+ if( !bPageValid )
+ bAllValid = FALSE;
+ if ( aRepaint.HasArea() )
+ pImp->GetShell()->InvalidateWindows( aRepaint );
+ if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) )
+ return TRUE;
+ break;
+ }
+ case AUTOCOMPLETE_WORDS :
+ ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos );
+ if ( Application::AnyInput( INPUT_ANY ) )
+ return TRUE;
+ break;
+ case WORD_COUNT :
+ {
+ const xub_StrLen nEnd = pTxtNode->GetTxt().Len();
+ SwDocStat aStat;
+ pTxtNode->CountWords( aStat, 0, nEnd );
+ if ( Application::AnyInput( INPUT_ANY ) )
+ return TRUE;
+ break;
+ }
+ case SMART_TAGS : // SMARTTAGS
+ {
+ const SwRect aRepaint( ((SwTxtFrm*)pCnt)->SmartTagScan( pCntntNode, nTxtPos ) );
+ bPageValid = bPageValid && !pTxtNode->IsSmartTagDirty();
+ if( !bPageValid )
+ bAllValid = FALSE;
+ if ( aRepaint.HasArea() )
+ pImp->GetShell()->InvalidateWindows( aRepaint );
+ if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) )
+ return TRUE;
+ break;
+ }
+ }
+ }
+
+ //Die im Absatz verankerten Flys wollen auch mitspielen.
+ if ( pCnt->GetDrawObjs() )
+ {
+ const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
+ for ( USHORT i = 0; i < rObjs.Count(); ++i )
+ {
+ SwAnchoredObject* pObj = rObjs[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
+ if ( pFly->IsFlyInCntFrm() )
+ {
+ const SwCntntFrm *pC = pFly->ContainsCntnt();
+ while( pC )
+ {
+ if ( pC->IsTxtFrm() )
+ {
+ if ( _DoIdleJob( pC, eJob ) )
+ return TRUE;
+ }
+ pC = pC->GetNextCntntFrm();
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOL SwLayIdle::DoIdleJob( IdleJobType eJob, BOOL bVisAreaOnly )
+{
+ //Spellchecken aller Inhalte der Seiten. Entweder nur der sichtbaren
+ //Seiten oder eben aller.
+ const ViewShell* pViewShell = pImp->GetShell();
+ const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
+ const SwDoc* pDoc = pViewShell->GetDoc();
+
+ switch ( eJob )
+ {
+ case ONLINE_SPELLING :
+ if( !pViewOptions->IsOnlineSpell() )
+ return FALSE;
+ break;
+ case AUTOCOMPLETE_WORDS :
+ if( !pViewOptions->IsAutoCompleteWords() ||
+ pDoc->GetAutoCompleteWords().IsLockWordLstLocked())
+ return FALSE;
+ break;
+ case WORD_COUNT :
+ if ( !pViewShell->getIDocumentStatistics()->GetDocStat().bModified )
+ return FALSE;
+ break;
+ case SMART_TAGS :
+ if ( pDoc->GetDocShell()->IsHelpDocument() ||
+ pDoc->isXForms() ||
+ !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
+ return FALSE;
+ break;
+ default: ASSERT( false, "Unknown idle job type" )
+ }
+
+ SwPageFrm *pPage;
+ if ( bVisAreaOnly )
+ pPage = pImp->GetFirstVisPage();
+ else
+ pPage = (SwPageFrm*)pRoot->Lower();
+
+ pCntntNode = NULL;
+ nTxtPos = STRING_LEN;
+
+ while ( pPage )
+ {
+ bPageValid = TRUE;
+ const SwCntntFrm *pCnt = pPage->ContainsCntnt();
+ while( pCnt && pPage->IsAnLower( pCnt ) )
+ {
+ if ( _DoIdleJob( pCnt, eJob ) )
+ return TRUE;
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+ if ( pPage->GetSortedObjs() )
+ {
+ for ( USHORT i = 0; pPage->GetSortedObjs() &&
+ i < pPage->GetSortedObjs()->Count(); ++i )
+ {
+ const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
+ const SwCntntFrm *pC = pFly->ContainsCntnt();
+ while( pC )
+ {
+ if ( pC->IsTxtFrm() )
+ {
+ if ( _DoIdleJob( pC, eJob ) )
+ return TRUE;
+ }
+ pC = pC->GetNextCntntFrm();
+ }
+ }
+ }
+ }
+
+ if( bPageValid )
+ {
+ switch ( eJob )
+ {
+ case ONLINE_SPELLING : pPage->ValidateSpelling(); break;
+ case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break;
+ case WORD_COUNT : pPage->ValidateWordCount(); break;
+ case SMART_TAGS : pPage->ValidateSmartTags(); break; // SMARTTAGS
+ }
+ }
+
+ pPage = (SwPageFrm*)pPage->GetNext();
+ if ( pPage && bVisAreaOnly &&
+ !pPage->Frm().IsOver( pImp->GetShell()->VisArea()))
+ break;
+ }
+ return FALSE;
+}
+
+
+#ifdef DBG_UTIL
+#if OSL_DEBUG_LEVEL > 1
+
+/*************************************************************************
+|*
+|* void SwLayIdle::SwLayIdle()
+|*
+|* Ersterstellung MA ??
+|* Letzte Aenderung MA 09. Jun. 94
+|*
+|*************************************************************************/
+void SwLayIdle::ShowIdle( ColorData eColorData )
+{
+ if ( !bIndicator )
+ {
+ bIndicator = TRUE;
+ Window *pWin = pImp->GetShell()->GetWin();
+ if ( pWin )
+ {
+ Rectangle aRect( 0, 0, 5, 5 );
+ aRect = pWin->PixelToLogic( aRect );
+ // OD 2004-04-23 #116347#
+ pWin->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+ pWin->SetFillColor( eColorData );
+ pWin->SetLineColor();
+ pWin->DrawRect( aRect );
+ pWin->Pop();
+ }
+ }
+}
+#define SHOW_IDLE( ColorData ) ShowIdle( ColorData )
+#else
+#define SHOW_IDLE( ColorData )
+#endif
+#else
+#define SHOW_IDLE( ColorData )
+#endif
+
+/*************************************************************************
+|*
+|* void SwLayIdle::SwLayIdle()
+|*
+|* Ersterstellung MA 30. Oct. 92
+|* Letzte Aenderung MA 23. May. 95
+|*
+|*************************************************************************/
+SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) :
+ pRoot( pRt ),
+ pImp( pI )
+#ifdef DBG_UTIL
+#if OSL_DEBUG_LEVEL > 1
+ , bIndicator( FALSE )
+#endif
+#endif
+{
+ pImp->pIdleAct = this;
+
+ SHOW_IDLE( COL_LIGHTRED );
+
+ pImp->GetShell()->EnableSmooth( FALSE );
+
+ //Zuerst den Sichtbaren Bereich Spellchecken, nur wenn dort nichts
+ //zu tun war wird das IdleFormat angestossen.
+ if ( !DoIdleJob( SMART_TAGS, TRUE ) &&
+ !DoIdleJob( ONLINE_SPELLING, TRUE ) &&
+ !DoIdleJob( AUTOCOMPLETE_WORDS, TRUE ) ) // SMARTTAGS
+ {
+ //Formatieren und ggf. Repaint-Rechtecke an der ViewShell vormerken.
+ //Dabei muessen kuenstliche Actions laufen, damit es z.B. bei
+ //Veraenderungen der Seitenzahl nicht zu unerwuenschten Effekten kommt.
+ //Wir merken uns bei welchen Shells der Cursor sichtbar ist, damit
+ //wir ihn bei Dokumentaenderung ggf. wieder sichbar machen koennen.
+ SvBools aBools;
+ ViewShell *pSh = pImp->GetShell();
+ do
+ { ++pSh->nStartAction;
+ BOOL bVis = FALSE;
+ if ( pSh->ISA(SwCrsrShell) )
+ {
+#ifdef SW_CRSR_TIMER
+ ((SwCrsrShell*)pSh)->ChgCrsrTimerFlag( FALSE );
+#endif
+ bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea());
+ }
+ aBools.Insert( bVis, aBools.Count() );
+ pSh = (ViewShell*)pSh->GetNext();
+ } while ( pSh != pImp->GetShell() );
+
+ SwLayAction aAction( pRoot, pImp );
+ aAction.SetInputType( INPUT_ANY );
+ aAction.SetIdle( TRUE );
+ aAction.SetWaitAllowed( FALSE );
+ aAction.Action();
+
+ //Weitere Start-/EndActions nur auf wenn irgendwo Paints aufgelaufen
+ //sind oder wenn sich die Sichtbarkeit des CharRects veraendert hat.
+ BOOL bActions = FALSE;
+ USHORT nBoolIdx = 0;
+ do
+ {
+ --pSh->nStartAction;
+
+ if ( pSh->Imp()->GetRegion() )
+ bActions = TRUE;
+ else
+ {
+ SwRect aTmp( pSh->VisArea() );
+ pSh->UISizeNotify();
+
+ // --> FME 2006-08-03 #137134#
+ // Are we supposed to crash if pSh isn't a cursor shell?!
+ // bActions |= aTmp != pSh->VisArea() ||
+ // aBools[nBoolIdx] != ((SwCrsrShell*)pSh)->GetCharRect().IsOver( pSh->VisArea() );
+
+ // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!)
+ // and the cursor is visible.
+ bActions |= aTmp != pSh->VisArea();
+ if ( aTmp == pSh->VisArea() && pSh->ISA(SwCrsrShell) )
+ {
+ bActions |= aBools[nBoolIdx] !=
+ static_cast<SwCrsrShell*>(pSh)->GetCharRect().IsOver( pSh->VisArea() );
+ }
+ }
+
+ pSh = (ViewShell*)pSh->GetNext();
+ ++nBoolIdx;
+ } while ( pSh != pImp->GetShell() );
+
+ if ( bActions )
+ {
+ //Start- EndActions aufsetzen. ueber die CrsrShell, damit der
+ //Cursor/Selektion und die VisArea korrekt gesetzt werden.
+ nBoolIdx = 0;
+ do
+ {
+ BOOL bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) );
+
+ if ( bCrsrShell )
+ ((SwCrsrShell*)pSh)->SttCrsrMove();
+// else
+// pSh->StartAction();
+
+ //Wenn Paints aufgelaufen sind, ist es am sinnvollsten schlicht das
+ //gesamte Window zu invalidieren. Anderfalls gibt es Paintprobleme
+ //deren Loesung unverhaeltnissmaessig aufwendig waere.
+ //fix(18176):
+ SwViewImp *pViewImp = pSh->Imp();
+ BOOL bUnlock = FALSE;
+ if ( pViewImp->GetRegion() )
+ {
+ pViewImp->DelRegion();
+
+ //Fuer Repaint mit virtuellem Device sorgen.
+ pSh->LockPaint();
+ bUnlock = TRUE;
+ }
+
+ if ( bCrsrShell )
+ //Wenn der Crsr sichbar war wieder sichbar machen, sonst
+ //EndCrsrMove mit TRUE fuer IdleEnd.
+ ((SwCrsrShell*)pSh)->EndCrsrMove( TRUE^aBools[nBoolIdx] );
+// else
+// pSh->EndAction();
+ if( bUnlock )
+ {
+ if( bCrsrShell )
+ {
+ // UnlockPaint overwrite the selection from the
+ // CrsrShell and calls the virtual method paint
+ // to fill the virtual device. This fill dont have
+ // paint the selection! -> Set the focus flag at
+ // CrsrShell and it dont paint the selection.
+ ((SwCrsrShell*)pSh)->ShLooseFcs();
+ pSh->UnlockPaint( TRUE );
+ ((SwCrsrShell*)pSh)->ShGetFcs( FALSE );
+ }
+ else
+ pSh->UnlockPaint( TRUE );
+ }
+
+ pSh = (ViewShell*)pSh->GetNext();
+ ++nBoolIdx;
+
+ } while ( pSh != pImp->GetShell() );
+ }
+
+ if ( !aAction.IsInterrupt() )
+ {
+ if ( !DoIdleJob( WORD_COUNT, FALSE ) )
+ if ( !DoIdleJob( SMART_TAGS, FALSE ) )
+ if ( !DoIdleJob( ONLINE_SPELLING, FALSE ) )
+ DoIdleJob( AUTOCOMPLETE_WORDS, FALSE ); // SMARTTAGS
+ }
+
+ bool bInValid = false;
+ const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions();
+ const ViewShell* pViewShell = pImp->GetShell();
+ // See conditions in DoIdleJob()
+ const BOOL bSpell = rVOpt.IsOnlineSpell();
+ const BOOL bACmplWrd = rVOpt.IsAutoCompleteWords();
+ const BOOL bWordCount = pViewShell->getIDocumentStatistics()->GetDocStat().bModified;
+ const BOOL bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() &&
+ !pViewShell->GetDoc()->isXForms() &&
+ SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
+
+ SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
+ do
+ {
+ bInValid = pPg->IsInvalidCntnt() || pPg->IsInvalidLayout() ||
+ pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() ||
+ pPg->IsInvalidFlyInCnt() ||
+ (bSpell && pPg->IsInvalidSpelling()) ||
+ (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) ||
+ (bWordCount && pPg->IsInvalidWordCount()) ||
+ (bSmartTags && pPg->IsInvalidSmartTags()); // SMARTTAGS
+
+ pPg = (SwPageFrm*)pPg->GetNext();
+
+ } while ( pPg && !bInValid );
+
+ if ( !bInValid )
+ {
+ pRoot->ResetIdleFormat();
+ SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell();
+ pDocShell->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) );
+ }
+ }
+
+ pImp->GetShell()->EnableSmooth( TRUE );
+
+ if( pImp->IsAccessible() )
+ pImp->FireAccessibleEvents();
+
+#ifdef DBG_UTIL
+#if OSL_DEBUG_LEVEL > 1
+ if ( bIndicator && pImp->GetShell()->GetWin() )
+ {
+ // #i75172# Do not invalidate indicator, this may cause a endless loop. Instead, just repaint it
+ // This should be replaced by an overlay object in the future, anyways. Since it's only for debug
+ // purposes, it is not urgent.
+ static bool bCheckWithoutInvalidating(true);
+ if(bCheckWithoutInvalidating)
+ {
+ bIndicator = false; SHOW_IDLE( COL_LIGHTGREEN );
+ }
+ else
+ {
+ Rectangle aRect( 0, 0, 5, 5 );
+ aRect = pImp->GetShell()->GetWin()->PixelToLogic( aRect );
+ pImp->GetShell()->GetWin()->Invalidate( aRect );
+ }
+ }
+#endif
+#endif
+}
+
+SwLayIdle::~SwLayIdle()
+{
+ pImp->pIdleAct = 0;
+}
+