diff options
author | Michael Meeks <michael.meeks@suse.com> | 2013-02-13 11:35:13 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2013-02-13 12:13:56 +0000 |
commit | c138a8aec8dccb97948a7d7993e6869da4079b32 (patch) | |
tree | 51efecacb1aad23c2a965fda20d1ac319501386f /sw/source | |
parent | add headers to new files (diff) | |
download | core-c138a8aec8dccb97948a7d7993e6869da4079b32.tar.gz core-c138a8aec8dccb97948a7d7993e6869da4079b32.zip |
asynchronous word-count.
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/core/doc/doc.cxx | 181 | ||||
-rw-r--r-- | sw/source/core/doc/docnew.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/txtnode/txtedt.cxx | 18 | ||||
-rw-r--r-- | sw/source/ui/dialog/wordcountdialog.cxx | 2 | ||||
-rw-r--r-- | sw/source/ui/inc/view.hxx | 6 | ||||
-rw-r--r-- | sw/source/ui/uiview/view.cxx | 1 | ||||
-rw-r--r-- | sw/source/ui/uiview/view2.cxx | 9 |
7 files changed, 132 insertions, 89 deletions
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index cd71cf5e6b27..0470ef3a2551 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -55,6 +55,7 @@ #include <editeng/rsiditem.hxx> #include <unotools/charclass.hxx> #include <unotools/localedatawrapper.hxx> +#include <vcl/timer.hxx> #include <swatrset.hxx> #include <swmodule.hxx> @@ -112,6 +113,7 @@ #include <shellres.hxx> #include <txtfrm.hxx> #include <attrhint.hxx> +#include <view.hxx> #include <wdocsh.hxx> // SwWebDocShell #include <prtopt.hxx> // SwPrintOptions @@ -1146,10 +1148,6 @@ bool SwDoc::UpdateParRsid( SwTxtNode *pTxtNode, sal_uInt32 nVal ) return pTxtNode->SetAttr( aRsid ); } - -/************************************************************************* - * void SetDocStat( const SwDocStat& rStat ); - *************************************************************************/ void SwDoc::SetDocStat( const SwDocStat& rStat ) { *pDocStat = rStat; @@ -1160,11 +1158,11 @@ const SwDocStat& SwDoc::GetDocStat() const return *pDocStat; } -const SwDocStat& SwDoc::GetUpdatedDocStat() +const SwDocStat& SwDoc::GetUpdatedDocStat( bool bCompleteAsync ) { - if (pDocStat->bModified) + if( pDocStat->bModified ) { - UpdateDocStat(); + UpdateDocStat( bCompleteAsync ); } return *pDocStat; } @@ -1686,92 +1684,117 @@ void SwDoc::CalculatePagePairsForProspectPrinting( // thus we are done here. } -/************************************************************************* - * void UpdateDocStat(); - *************************************************************************/ -void SwDoc::UpdateDocStat() +// returns true while there is more to do +bool SwDoc::IncrementalDocStatCalculate( long nTextNodes ) { - if( pDocStat->bModified ) - { - pDocStat->Reset(); - pDocStat->nPara = 0; // default is 1! - SwNode* pNd; + pDocStat->Reset(); + pDocStat->nPara = 0; // default is 1! + SwNode* pNd; - for( sal_uLong i = GetNodes().Count(); i; ) + // This is the inner loop - at least while the paras are dirty. + for( sal_uLong i = GetNodes().Count(); i > 0 && nTextNodes > 0; ) + { + switch( ( pNd = GetNodes()[ --i ])->GetNodeType() ) { - switch( ( pNd = GetNodes()[ --i ])->GetNodeType() ) - { - case ND_TEXTNODE: - ((SwTxtNode*)pNd)->CountWords( *pDocStat, 0, ((SwTxtNode*)pNd)->GetTxt().Len() ); - break; - case ND_TABLENODE: ++pDocStat->nTbl; break; - case ND_GRFNODE: ++pDocStat->nGrf; break; - case ND_OLENODE: ++pDocStat->nOLE; break; - case ND_SECTIONNODE: break; - } + case ND_TEXTNODE: + { + SwTxtNode *pTxt = static_cast< SwTxtNode * >( pNd ); + if( pTxt->CountWords( *pDocStat, 0, pTxt->GetTxt().Len() ) ) + nTextNodes--; + break; + } + case ND_TABLENODE: ++pDocStat->nTbl; break; + case ND_GRFNODE: ++pDocStat->nGrf; break; + case ND_OLENODE: ++pDocStat->nOLE; break; + case ND_SECTIONNODE: break; } + } - // #i93174#: notes contain paragraphs that are not nodes + // #i93174#: notes contain paragraphs that are not nodes + { + SwFieldType * const pPostits( GetSysFldType(RES_POSTITFLD) ); + SwIterator<SwFmtFld,SwFieldType> aIter( *pPostits ); + for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) { - SwFieldType * const pPostits( GetSysFldType(RES_POSTITFLD) ); - SwIterator<SwFmtFld,SwFieldType> aIter( *pPostits ); - for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) + if (pFmtFld->IsFldInDoc()) { - if (pFmtFld->IsFldInDoc()) - { - SwPostItField const * const pField( - static_cast<SwPostItField const*>(pFmtFld->GetFld())); - pDocStat->nAllPara += pField->GetNumberOfParagraphs(); - } + SwPostItField const * const pField( + static_cast<SwPostItField const*>(pFmtFld->GetFld())); + pDocStat->nAllPara += pField->GetNumberOfParagraphs(); } } + } - pDocStat->nPage = GetCurrentLayout() ? GetCurrentLayout()->GetPageNum() : 0; //swmod 080218 - pDocStat->bModified = sal_False; - - com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aStat( pDocStat->nPage ? 8 : 7); - sal_Int32 n=0; - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nTbl; - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nGrf; - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nOLE; - if ( pDocStat->nPage ) - { - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nPage; - } - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParagraphCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nPara; - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WordCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nWord; - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharacterCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nChar; - aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NonWhitespaceCharacterCount")); - aStat[n++].Value <<= (sal_Int32)pDocStat->nCharExcludingSpaces; - - // For e.g. autotext documents there is no pSwgInfo (#i79945) - SfxObjectShell * const pObjShell( GetDocShell() ); - if (pObjShell) - { - const uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + pDocStat->nPage = GetCurrentLayout() ? GetCurrentLayout()->GetPageNum() : 0; + pDocStat->bModified = sal_False; + + com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aStat( pDocStat->nPage ? 8 : 7); + sal_Int32 n=0; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nTbl; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nGrf; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nOLE; + if ( pDocStat->nPage ) + { + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nPage; + } + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParagraphCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nPara; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WordCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nWord; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharacterCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nChar; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NonWhitespaceCharacterCount")); + aStat[n++].Value <<= (sal_Int32)pDocStat->nCharExcludingSpaces; + + // For e.g. autotext documents there is no pSwgInfo (#i79945) + SfxObjectShell * const pObjShell( GetDocShell() ); + if (pObjShell) + { + const uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pObjShell->GetModel(), uno::UNO_QUERY_THROW); - const uno::Reference<document::XDocumentProperties> xDocProps( + const uno::Reference<document::XDocumentProperties> xDocProps( xDPS->getDocumentProperties()); - // #i96786#: do not set modified flag when updating statistics - const bool bDocWasModified( IsModified() ); - const ModifyBlocker_Impl b(pObjShell); - xDocProps->setDocumentStatistics(aStat); - if (!bDocWasModified) - { - ResetModified(); - } + // #i96786#: do not set modified flag when updating statistics + const bool bDocWasModified( IsModified() ); + const ModifyBlocker_Impl b(pObjShell); + xDocProps->setDocumentStatistics(aStat); + if (!bDocWasModified) + { + ResetModified(); } + } + + // optionally update stat. fields + SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD); + pType->UpdateFlds(); + + return nTextNodes <= 0; +} + +IMPL_LINK( SwDoc, DoIdleStatsUpdate, Timer *, pTimer ) +{ + (void)pTimer; + if( IncrementalDocStatCalculate( 1000 ) ) + aStatsUpdateTimer.Start(); - // optionally update stat. fields - SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD); - pType->UpdateFlds(); + SwView* pView = GetDocShell() ? GetDocShell()->GetView() : NULL; + if( pView ) + pView->UpdateDocStats(); + return 0; +} + +void SwDoc::UpdateDocStat( bool bCompleteAsync ) +{ + if( pDocStat->bModified ) + { + if (!bCompleteAsync) + while (IncrementalDocStatCalculate()) {} + else if (IncrementalDocStatCalculate()) + aStatsUpdateTimer.Start(); } } diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index 949cab186a13..7b1faa60025e 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -403,6 +403,9 @@ SwDoc::SwDoc() aOLEModifiedTimer.SetTimeout( 1000 ); aOLEModifiedTimer.SetTimeoutHdl( LINK( this, SwDoc, DoUpdateModifiedOLE )); + aStatsUpdateTimer.SetTimeout( 100 ); + aStatsUpdateTimer.SetTimeoutHdl( LINK( this, SwDoc, DoIdleStatsUpdate ) ); + // Create DBMgr pNewDBMgr = new SwNewDBMgr; @@ -508,6 +511,7 @@ SwDoc::~SwDoc() SetDefault(aCharFmt); StopIdling(); // stop idle timer + aStatsUpdateTimer.Stop(); delete pUnoCallBack, pUnoCallBack = 0; delete pURLStateChgd; diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx index d91bf7dd9d15..3c8503bab834 100644 --- a/sw/source/core/txtnode/txtedt.cxx +++ b/sw/source/core/txtnode/txtedt.cxx @@ -1854,22 +1854,24 @@ void SwTxtNode::ReplaceTextOnly( xub_StrLen nPos, xub_StrLen nLen, NotifyClients( 0, &aHint ); } -void SwTxtNode::CountWords( SwDocStat& rStat, +// the return values allows us to see if we did the heavy- +// lifting required to actually break and count the words. +bool SwTxtNode::CountWords( SwDocStat& rStat, xub_StrLen nStt, xub_StrLen nEnd ) const { if( nStt > nEnd ) { // bad call - return; + return false; } if (IsInRedlines()) { //not counting txtnodes used to hold deleted redline content - return; + return false; } bool bCountAll = ( (0 == nStt) && (GetTxt().Len() == nEnd) ); ++rStat.nAllPara; // #i93174#: count _all_ paragraphs if ( IsHidden() ) { // not counting hidden paras - return; + return false; } // count words in numbering string if started at beginning of para: bool bCountNumbering = nStt == 0; @@ -1886,7 +1888,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat, if( nStt == nEnd && !bCountNumbering) { // unnumbered empty node or empty selection - return; + return false; } // count of non-empty paras @@ -1900,7 +1902,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat, rStat.nAsianWord += GetParaNumberOfAsianWords(); rStat.nChar += GetParaNumberOfChars(); rStat.nCharExcludingSpaces += GetParaNumberOfCharsExcludingSpaces(); - return; + return false; } // ConversionMap to expand fields, remove invisible and redline deleted text for scanner @@ -1914,7 +1916,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat, if (aExpandText.isEmpty() && !bCountNumbering) { OSL_ENSURE(aExpandText.getLength() >= 0, "Node text expansion error: length < 0." ); - return; + return false; } //do the count @@ -2002,6 +2004,8 @@ void SwTxtNode::CountWords( SwDocStat& rStat, rStat.nAsianWord += nTmpAsianWords; rStat.nChar += nTmpChars; rStat.nCharExcludingSpaces += nTmpCharsExcludingSpaces; + + return true; } // diff --git a/sw/source/ui/dialog/wordcountdialog.cxx b/sw/source/ui/dialog/wordcountdialog.cxx index ff777ace9502..6d8d738b25bf 100644 --- a/sw/source/ui/dialog/wordcountdialog.cxx +++ b/sw/source/ui/dialog/wordcountdialog.cxx @@ -32,7 +32,7 @@ #include <vcl/msgbox.hxx> IMPL_LINK_NOARG(SwWordCountFloatDlg, CloseHdl) -{ +{ SfxViewFrame* pVFrame = ::GetActiveView()->GetViewFrame(); if (pVFrame != NULL) { diff --git a/sw/source/ui/inc/view.hxx b/sw/source/ui/inc/view.hxx index 2cfcf389fdae..d0a542bdcc35 100644 --- a/sw/source/ui/inc/view.hxx +++ b/sw/source/ui/inc/view.hxx @@ -358,7 +358,9 @@ class SW_DLLPUBLIC SwView: public SfxViewShell SW_DLLPRIVATE virtual void Move(); - SW_DLLPRIVATE sal_Bool InsertGraphicDlg( SfxRequest& ); + SW_DLLPRIVATE sal_Bool InsertGraphicDlg( SfxRequest& ); + + SW_DLLPRIVATE void DocumentStatsChanged(); protected: @@ -656,6 +658,8 @@ public: // exhibition hack (MA,MBA) void SelectShellForDrop(); + + void UpdateDocStats(); }; // ----------------- inline Methoden ---------------------- diff --git a/sw/source/ui/uiview/view.cxx b/sw/source/ui/uiview/view.cxx index 1ad946c0863b..26a135da34bd 100644 --- a/sw/source/ui/uiview/view.cxx +++ b/sw/source/ui/uiview/view.cxx @@ -1055,6 +1055,7 @@ SwView::~SwView() bInDtor = sal_True; pEditWin->Hide(); // damit kein Paint Aerger machen kann! // An der SwDocShell den Pointer auf die View ruecksetzen + SwDocShell* pDocSh = GetDocShell(); if( pDocSh && pDocSh->GetView() == this ) pDocSh->SetView( 0 ); diff --git a/sw/source/ui/uiview/view2.cxx b/sw/source/ui/uiview/view2.cxx index f5aff2af3675..0414f685589d 100644 --- a/sw/source/ui/uiview/view2.cxx +++ b/sw/source/ui/uiview/view2.cxx @@ -1203,6 +1203,13 @@ void SwView::UpdatePageNums(sal_uInt16 nPhyNum, sal_uInt16 nVirtNum, const Strin rBnd.Update( FN_STAT_PAGE ); } +void SwView::UpdateDocStats() +{ + SfxBindings &rBnd = GetViewFrame()->GetBindings(); + rBnd.Invalidate( FN_STAT_WORDCOUNT ); + rBnd.Update( FN_STAT_WORDCOUNT ); +} + /*-------------------------------------------------------------------- Beschreibung: Status der Stauszeile --------------------------------------------------------------------*/ @@ -1241,7 +1248,7 @@ void SwView::StateStatusLine(SfxItemSet &rSet) SwDocStat documentStats; { rShell.CountWords(selectionStats); - documentStats = rShell.GetDoc()->GetUpdatedDocStat(); + documentStats = rShell.GetDoc()->GetUpdatedDocStat( true /* complete-async */ ); } const sal_uInt32 stringId = selectionStats.nWord? STR_STATUSBAR_WORDCOUNT : STR_STATUSBAR_WORDCOUNT_NO_SELECTION; |