Hello, I'm sending this patch to fix Writer's aIdleTimer.
diff --git a/sw/inc/IDocumentTimerAccess.hxx b/sw/inc/IDocumentTimerAccess.hxx index 84e3cd4..458ad79 100644 --- a/sw/inc/IDocumentTimerAccess.hxx +++ b/sw/inc/IDocumentTimerAccess.hxx @@ -20,31 +20,41 @@ #ifndef IDOCUMENTTIMERACCESS_HXX_INCLUDED #define IDOCUMENTTIMERACCESS_HXX_INCLUDED - /** Get information about the current document state + /** Manipulate background jobs of the document. It starts with a mode of + 'stopped' and a block count of 0. */ class IDocumentTimerAccess { public: /** - Set modus to start, i.e. start timer if block count == 0 + Set modus to 'start'. */ virtual void StartIdling() = 0; /** - Set modus to stopped, i.e. stop timer if running + Set mode to 'stopped'. */ virtual void StopIdling() = 0; /** - Increment block count, stop timer if running + Increment block count. */ virtual void BlockIdling() = 0; /** - Decrement block count, start timer if block count == 0 AND modus == start + Decrement block count. */ virtual void UnblockIdling() = 0; + /** + Do these jobs asynchronously: do grammar checking, + do layout, and update fields. + They will be delayed until mode is start AND block count == 0. + The implementation might delay them further, for example + it might wait until the application is idle. + */ + virtual void StartBackgroundJobs() = 0; + protected: virtual ~IDocumentTimerAccess() {}; }; diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index ae910d8..51d669c 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -972,6 +972,7 @@ public: virtual void StopIdling(); virtual void BlockIdling(); virtual void UnblockIdling(); + virtual void StartBackgroundJobs(); /** IDocumentChartDataProviderAccess */ diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx index 18953ad..7f6e6ac 100644 --- a/sw/source/core/doc/docfld.cxx +++ b/sw/source/core/doc/docfld.cxx @@ -2564,8 +2564,8 @@ void SwDocUpdtFld::RemoveFldType( const SwFieldType& rType ) } } -SwDocUpdtFld::SwDocUpdtFld() - : pFldSortLst(0), nFldLstGetMode(0) +SwDocUpdtFld::SwDocUpdtFld(SwDoc* pDoc) + : pFldSortLst(0), nFldLstGetMode(0), pDocument(pDoc) { bInUpdateFlds = bFldsDirty = sal_False; memset( aFldTypeTable, 0, sizeof( aFldTypeTable ) ); diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 06b10d5..c4079c5 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1826,6 +1826,11 @@ void SwDoc::UnblockIdling() aIdleTimer.Start(); } +void SwDoc::StartBackgroundJobs() { + // Trigger DoIdleJobs(), asynchronously. + aIdleTimer.Start(); +} + /************************************************************************* |* |* SwDoc::DoIdleJobs() @@ -1846,11 +1851,10 @@ IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer ) ViewShell *pSh, *pStartSh; pSh = pStartSh = GetCurrentViewShell(); do { if( pSh->ActionPend() ) { - if( pTimer ) - pTimer->Start(); + pTimer->Start(); return 0; } pSh = (ViewShell*)pSh->GetNext(); } while( pSh != pStartSh ); @@ -1865,28 +1869,35 @@ IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer ) if (bIsOnlineSpell && bIsAutoGrammar) StartGrammarChecking( *this ); } - SwFldUpdateFlags nFldUpdFlag; std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080320 std::set<SwRootFrm*>::iterator pLayIter = aAllLayouts.begin(); for ( ;pLayIter != aAllLayouts.end();++pLayIter ) { if ((*pLayIter)->IsIdleFormat()) { (*pLayIter)->GetCurrShell()->LayoutIdle(); - break; + + // Defer the remaining work. + pTimer->Start(); + return 0; } } - bool bAllValid = pLayIter == aAllLayouts.end() ? 1 : 0; - if( bAllValid && ( AUTOUPD_FIELD_ONLY == - ( nFldUpdFlag = getFieldUpdateFlags(true) ) + + SwFldUpdateFlags nFldUpdFlag = getFieldUpdateFlags(true); + if( ( AUTOUPD_FIELD_ONLY == nFldUpdFlag || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) && - GetUpdtFlds().IsFieldsDirty() && - !GetUpdtFlds().IsInUpdateFlds() && - !IsExpFldsLocked() + GetUpdtFlds().IsFieldsDirty() // If we switch the field name the Fields are not updated. // So the "backgorund update" should always be carried out /* && !pStartSh->GetViewOptions()->IsFldName()*/ ) { + if ( !GetUpdtFlds().IsInUpdateFlds() && + !IsExpFldsLocked() ) + { + pTimer->Start(); + return 0; + } + // Action brackets! GetUpdtFlds().SetInUpdateFlds( true ); @@ -1912,9 +1923,7 @@ IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer ) #ifdef TIMELOG if( pModLogFile && 1 != (long)pModLogFile ) delete pModLogFile, ((long&)pModLogFile) = 1; #endif - if( pTimer ) - pTimer->Start(); return 0; } diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index f2ac06e..0519309 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -220,7 +220,7 @@ SwDoc::SwDoc() pDefTOXBases( new SwDefTOXBase_Impl() ), pCurrentView( 0 ), //swmod 071225 pDrawModel( 0 ), - pUpdtFlds( new SwDocUpdtFld() ), + pUpdtFlds( new SwDocUpdtFld( this ) ), pFldTypes( new SwFldTypes() ), pVirDev( 0 ), pPrt( 0 ), diff --git a/sw/source/core/inc/docfld.hxx b/sw/source/core/inc/docfld.hxx index 4ded5cc..a823c55 100644 --- a/sw/source/core/inc/docfld.hxx +++ b/sw/source/core/inc/docfld.hxx @@ -30,6 +30,7 @@ #define _DOCFLD_HXX #include <calc.hxx> +#include <doc.hxx> #include <o3tl/sorted_vector.hxx> class SwTxtFld; @@ -155,6 +156,7 @@ class SwDocUpdtFld sal_uLong nNodes; // if the node count is different sal_uInt8 nFldLstGetMode; + SwDoc* pDocument; bool bInUpdateFlds : 1; // currently there is an UpdateFlds bool bFldsDirty : 1; // some fields are invalid @@ -164,7 +166,7 @@ class SwDocUpdtFld void GetBodyNode( const SwSectionNode&); public: - SwDocUpdtFld(); + SwDocUpdtFld(SwDoc* pDocument); ~SwDocUpdtFld(); const _SetGetExpFlds* GetSortLst() const { return pFldSortLst; } @@ -180,7 +182,11 @@ public: void SetInUpdateFlds( bool b ) { bInUpdateFlds = b; } bool IsFieldsDirty() const { return bFldsDirty; } - void SetFieldsDirty( bool b ) { bFldsDirty = b; } + void SetFieldsDirty( bool b ) + { + bFldsDirty = b; + pDocument->StartBackgroundJobs(); + } SwHash** GetFldTypeTable() const { return (SwHash**)aFldTypeTable; } }; diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx index 02014dc..1672c4c 100644 --- a/sw/source/core/inc/rootfrm.hxx +++ b/sw/source/core/inc/rootfrm.hxx @@ -29,6 +29,8 @@ #define SW_ROOTFRM_HXX #include "layfrm.hxx" +#include <viewsh.hxx> +#include <doc.hxx> class SwCntntFrm; class ViewShell; @@ -212,12 +214,30 @@ public: virtual Size ChgSize( const Size& aNewSize ); - void SetIdleFlags() { bIdleFormat = sal_True; } + void SetIdleFlags() + { + bIdleFormat = sal_True; + + ViewShell* lcl_pCurrShell = GetCurrShell(); + // May be NULL if called from SfxBaseModel::dispose + // (this happens in the build test 'rtfexport'). + if (lcl_pCurrShell != NULL) + lcl_pCurrShell->GetDoc()->StartBackgroundJobs(); + } sal_Bool IsIdleFormat() const { return bIdleFormat; } void ResetIdleFormat() { bIdleFormat = sal_False; } bool IsNeedGrammarCheck() const { return mbNeedGrammarCheck; } - void SetNeedGrammarCheck( bool bVal ) { mbNeedGrammarCheck = bVal; } + void SetNeedGrammarCheck( bool bVal ) + { + mbNeedGrammarCheck = bVal; + + ViewShell* lcl_pCurrShell = GetCurrShell(); + // May be NULL if called from SfxBaseModel::dispose + // (this happens in the build test 'rtfexport'). + if (lcl_pCurrShell != NULL) + lcl_pCurrShell->GetDoc()->StartBackgroundJobs(); + } //Sorgt dafuer, dass alle gewuenschten Seitengebunden Flys eine Seite finden void SetAssertFlyPages() { bAssertFlyPages = sal_True; }
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice