LCOV - code coverage report
Current view: top level - sw/source/core/doc - DocumentStatisticsManager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 113 114 99.1 %
Date: 2015-06-13 12:38:46 Functions: 16 16 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include <DocumentStatisticsManager.hxx>
      20             : #include <doc.hxx>
      21             : #include <editsh.hxx>
      22             : #include <fldbas.hxx>
      23             : #include <docsh.hxx>
      24             : #include <IDocumentFieldsAccess.hxx>
      25             : #include <IDocumentState.hxx>
      26             : #include <IDocumentLayoutAccess.hxx>
      27             : #include <view.hxx>
      28             : #include <ndtxt.hxx>
      29             : #include <calbck.hxx>
      30             : #include <fmtfld.hxx>
      31             : #include <rootfrm.hxx>
      32             : #include <docufld.hxx>
      33             : #include <docstat.hxx>
      34             : #include <vector>
      35             : #include <viewsh.hxx>
      36             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      37             : 
      38             : using namespace ::com::sun::star;
      39             : 
      40             : namespace
      41             : {
      42             :     class LockAllViews
      43             :     {
      44             :         std::vector<SwViewShell*> m_aViewWasUnLocked;
      45             :         SwViewShell* m_pViewShell;
      46             :     public:
      47        1103 :         explicit LockAllViews(SwViewShell *pViewShell)
      48        1103 :             : m_pViewShell(pViewShell)
      49             :         {
      50        1103 :             if (!m_pViewShell)
      51        1112 :                 return;
      52        2188 :             for(SwViewShell& rShell : m_pViewShell->GetRingContainer())
      53             :             {
      54        1094 :                 if(rShell.IsViewLocked())
      55             :                 {
      56          66 :                     m_aViewWasUnLocked.push_back(&rShell);
      57          66 :                     rShell.LockView(true);
      58             :                 }
      59             :             }
      60             :         }
      61        1103 :         ~LockAllViews()
      62        1103 :         {
      63        1169 :             for(SwViewShell* pShell : m_aViewWasUnLocked)
      64          66 :                 pShell->LockView(false);
      65        1103 :         }
      66             :     };
      67             : }
      68             : 
      69             : namespace sw
      70             : {
      71             : 
      72        2958 : DocumentStatisticsManager::DocumentStatisticsManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
      73        2958 :                                                                           mpDocStat( new SwDocStat )
      74             : {
      75        2958 :     maStatsUpdateTimer.SetTimeout( 1 );
      76        2958 :     maStatsUpdateTimer.SetPriority( SchedulerPriority::LOWEST );
      77        2958 :     maStatsUpdateTimer.SetTimeoutHdl( LINK( this, DocumentStatisticsManager, DoIdleStatsUpdate ) );
      78        2958 : }
      79             : 
      80        4216 : void DocumentStatisticsManager::DocInfoChgd( )
      81             : {
      82        4216 :     m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( RES_DOCINFOFLD )->UpdateFields();
      83        4216 :     m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( RES_TEMPLNAMEFLD )->UpdateFields();
      84        4216 :     m_rDoc.getIDocumentState().SetModified();
      85        4216 : }
      86             : 
      87    53556309 : const SwDocStat& DocumentStatisticsManager::GetDocStat() const
      88             : {
      89    53556309 :     return *mpDocStat;
      90             : }
      91             : 
      92     1001754 : SwDocStat& DocumentStatisticsManager::GetDocStat()
      93             : {
      94     1001754 :     return *mpDocStat;
      95             : }
      96             : 
      97         959 : const SwDocStat& DocumentStatisticsManager::GetUpdatedDocStat( bool bCompleteAsync, bool bFields )
      98             : {
      99         959 :     if( mpDocStat->bModified )
     100             :     {
     101         925 :         UpdateDocStat( bCompleteAsync, bFields );
     102             :     }
     103         959 :     return *mpDocStat;
     104             : }
     105             : 
     106         283 : void DocumentStatisticsManager::SetDocStat( const SwDocStat& rStat )
     107             : {
     108         283 :     *mpDocStat = rStat;
     109         283 : }
     110             : 
     111        1085 : void DocumentStatisticsManager::UpdateDocStat( bool bCompleteAsync, bool bFields )
     112             : {
     113        1085 :     if( mpDocStat->bModified )
     114             :     {
     115        1085 :         if (!bCompleteAsync)
     116             :         {
     117         396 :             while (IncrementalDocStatCalculate(
     118         198 :                         ::std::numeric_limits<long>::max(), bFields)) {}
     119         198 :             maStatsUpdateTimer.Stop();
     120             :         }
     121         887 :         else if (IncrementalDocStatCalculate(5000, bFields))
     122          18 :             maStatsUpdateTimer.Start();
     123             :         else
     124         869 :             maStatsUpdateTimer.Stop();
     125             :     }
     126        1085 : }
     127             : 
     128             : // returns true while there is more to do
     129        1103 : bool DocumentStatisticsManager::IncrementalDocStatCalculate(long nChars, bool bFields)
     130             : {
     131        1103 :     mpDocStat->Reset();
     132        1103 :     mpDocStat->nPara = 0; // default is 1!
     133             : 
     134             :     // This is the inner loop - at least while the paras are dirty.
     135       21951 :     for( sal_uLong i = m_rDoc.GetNodes().Count(); i > 0 && nChars > 0; )
     136             :     {
     137             :         SwNode* pNd;
     138       19745 :         switch( ( pNd = m_rDoc.GetNodes()[ --i ])->GetNodeType() )
     139             :         {
     140             :         case ND_TEXTNODE:
     141             :         {
     142        5936 :             long const nOldChars(mpDocStat->nChar);
     143        5936 :             SwTextNode *pText = static_cast< SwTextNode * >( pNd );
     144        5936 :             if (pText->CountWords(*mpDocStat, 0, pText->GetText().getLength()))
     145             :             {
     146         779 :                 nChars -= (mpDocStat->nChar - nOldChars);
     147             :             }
     148        5936 :             break;
     149             :         }
     150          71 :         case ND_TABLENODE:      ++mpDocStat->nTable;   break;
     151          22 :         case ND_GRFNODE:        ++mpDocStat->nGrf;   break;
     152          11 :         case ND_OLENODE:        ++mpDocStat->nOLE;   break;
     153          83 :         case ND_SECTIONNODE:    break;
     154             :         }
     155             :     }
     156             : 
     157             :     // #i93174#: notes contain paragraphs that are not nodes
     158             :     {
     159        1103 :         SwFieldType * const pPostits( m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(RES_POSTITFLD) );
     160        1103 :         SwIterator<SwFormatField,SwFieldType> aIter( *pPostits );
     161        1147 :         for( SwFormatField* pFormatField = aIter.First(); pFormatField;  pFormatField = aIter.Next() )
     162             :         {
     163          44 :             if (pFormatField->IsFieldInDoc())
     164             :             {
     165             :                 SwPostItField const * const pField(
     166          44 :                     static_cast<SwPostItField const*>(pFormatField->GetField()));
     167          44 :                 mpDocStat->nAllPara += pField->GetNumberOfParagraphs();
     168             :             }
     169        1103 :         }
     170             :     }
     171             : 
     172        1103 :     mpDocStat->nPage     = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout() ? m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->GetPageNum() : 0;
     173        1103 :     mpDocStat->bModified = false;
     174             : 
     175        1103 :     com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aStat( mpDocStat->nPage ? 8 : 7);
     176        1103 :     sal_Int32 n=0;
     177        1103 :     aStat[n].Name = "TableCount";
     178        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nTable;
     179        1103 :     aStat[n].Name = "ImageCount";
     180        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nGrf;
     181        1103 :     aStat[n].Name = "ObjectCount";
     182        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nOLE;
     183        1103 :     if ( mpDocStat->nPage )
     184             :     {
     185        1094 :         aStat[n].Name = "PageCount";
     186        1094 :         aStat[n++].Value <<= (sal_Int32)mpDocStat->nPage;
     187             :     }
     188        1103 :     aStat[n].Name = "ParagraphCount";
     189        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nPara;
     190        1103 :     aStat[n].Name = "WordCount";
     191        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nWord;
     192        1103 :     aStat[n].Name = "CharacterCount";
     193        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nChar;
     194        1103 :     aStat[n].Name = "NonWhitespaceCharacterCount";
     195        1103 :     aStat[n++].Value <<= (sal_Int32)mpDocStat->nCharExcludingSpaces;
     196             : 
     197             :     // For e.g. autotext documents there is no pSwgInfo (#i79945)
     198        1103 :     SwDocShell* pObjShell(m_rDoc.GetDocShell());
     199        1103 :     if (pObjShell)
     200             :     {
     201             :         const uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
     202        1103 :                 pObjShell->GetModel(), uno::UNO_QUERY_THROW);
     203             :         const uno::Reference<document::XDocumentProperties> xDocProps(
     204        2206 :                 xDPS->getDocumentProperties());
     205             :         // #i96786#: do not set modified flag when updating statistics
     206        1103 :         const bool bDocWasModified( m_rDoc.getIDocumentState().IsModified() );
     207        2206 :         const ModifyBlocker_Impl b(pObjShell);
     208             :         // rhbz#1081176: don't jump to cursor pos because of (temporary)
     209             :         // activation of modified flag triggering move to input position
     210        2206 :         LockAllViews aViewGuard(pObjShell->GetEditShell());
     211        1103 :         xDocProps->setDocumentStatistics(aStat);
     212        1103 :         if (!bDocWasModified)
     213             :         {
     214         402 :             m_rDoc.getIDocumentState().ResetModified();
     215        1103 :         }
     216             :     }
     217             : 
     218             :     // optionally update stat. fields
     219        1103 :     if (bFields)
     220             :     {
     221         216 :         SwFieldType *pType = m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(RES_DOCSTATFLD);
     222         216 :         pType->UpdateFields();
     223             :     }
     224             : 
     225        1103 :     return nChars < 0;
     226             : }
     227             : 
     228          36 : IMPL_LINK_TYPED( DocumentStatisticsManager, DoIdleStatsUpdate, Timer *, pTimer, void )
     229             : {
     230             :     (void)pTimer;
     231          18 :     if (IncrementalDocStatCalculate(32000))
     232           0 :         maStatsUpdateTimer.Start();
     233             : 
     234          18 :     SwView* pView = m_rDoc.GetDocShell() ? m_rDoc.GetDocShell()->GetView() : NULL;
     235          18 :     if( pView )
     236          18 :         pView->UpdateDocStats();
     237          18 : }
     238             : 
     239        8847 : DocumentStatisticsManager::~DocumentStatisticsManager()
     240             : {
     241        2949 :     maStatsUpdateTimer.Stop();
     242        2949 :     delete mpDocStat;
     243        5898 : }
     244             : 
     245         177 : }
     246             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11