LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sfx2/source/bastyp - progress.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 118 164 72.0 %
Date: 2013-07-09 Functions: 16 20 80.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             : 
      20             : 
      21             : #include <sfx2/progress.hxx>
      22             : #include <com/sun/star/uno/Reference.hxx>
      23             : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
      24             : 
      25             : #include <basic/sbx.hxx>
      26             : 
      27             : #include <svl/eitem.hxx>
      28             : #include <tools/time.hxx>
      29             : 
      30             : #include "appdata.hxx"
      31             : #include <sfx2/request.hxx>
      32             : #include <sfx2/frame.hxx>
      33             : #include <sfx2/viewfrm.hxx>
      34             : #include <sfx2/viewsh.hxx>
      35             : #include <sfx2/objsh.hxx>
      36             : #include <sfx2/app.hxx>
      37             : #include <sfx2/dispatch.hxx>
      38             : #include "sfxtypes.hxx"
      39             : #include <sfx2/docfile.hxx>
      40             : #include "workwin.hxx"
      41             : #include "sfx2/sfxresid.hxx"
      42             : #include "bastyp.hrc"
      43             : #include <sfx2/msg.hxx>
      44             : 
      45             : #include <time.h>
      46             : 
      47             : using namespace ::com::sun::star::uno;
      48             : using namespace ::com::sun::star::frame;
      49             : using namespace ::com::sun::star::task;
      50             : 
      51         721 : struct SfxProgress_Impl
      52             : {
      53             :     Reference < XStatusIndicator > xStatusInd;
      54             :     String                  aText, aStateText;
      55             :     sal_uIntPtr                 nMax;
      56             :     clock_t                 nCreate;
      57             :     clock_t                 nNextReschedule;
      58             :     sal_Bool                    bLocked, bAllDocs;
      59             :     sal_Bool                    bWaitMode;
      60             :     sal_Bool                    bAllowRescheduling;
      61             :     sal_Bool                    bRunning;
      62             : 
      63             :     SfxProgress*            pActiveProgress;
      64             :     SfxObjectShellRef       xObjSh;
      65             :     SfxWorkWindow*          pWorkWin;
      66             :     SfxViewFrame*           pView;
      67             : 
      68             :                             SfxProgress_Impl( const String& );
      69             :     void                    Enable_Impl( sal_Bool );
      70             : 
      71             : };
      72             : 
      73             : //========================================================================
      74             : 
      75             : #include "sfxslots.hxx"
      76             : 
      77             : //========================================================================
      78             : extern sal_uInt32 Get10ThSec();
      79             : 
      80             : // -----------------------------------------------------------------------
      81             : 
      82           0 : void SfxProgress_Impl::Enable_Impl( sal_Bool bEnable )
      83             : {
      84           0 :     SfxObjectShell* pDoc = bAllDocs ? NULL : (SfxObjectShell*) xObjSh;
      85           0 :     SfxViewFrame *pFrame= SfxViewFrame::GetFirst(pDoc);
      86           0 :     while ( pFrame )
      87             :     {
      88           0 :         pFrame->Enable(bEnable);
      89           0 :         pFrame->GetDispatcher()->Lock( !bEnable );
      90           0 :         pFrame = SfxViewFrame::GetNext(*pFrame, pDoc);
      91             :     }
      92             : 
      93           0 :     if ( pView )
      94             :     {
      95           0 :         pView->Enable( bEnable );
      96           0 :         pView->GetDispatcher()->Lock( !bEnable );
      97             :     }
      98             : 
      99           0 :     if ( !pDoc )
     100           0 :         SFX_APP()->GetAppDispatcher_Impl()->Lock( !bEnable );
     101           0 : }
     102             : 
     103             : // -----------------------------------------------------------------------
     104             : 
     105         721 : SfxProgress_Impl::SfxProgress_Impl( const String &/*rTitle*/ )
     106         721 :     : pActiveProgress(0), pWorkWin(0), pView(0)
     107             : {
     108         721 : }
     109             : 
     110             : // -----------------------------------------------------------------------
     111             : 
     112         721 : SfxProgress::SfxProgress
     113             : (
     114             :     SfxObjectShell*     pObjSh, /*  The action is performed on the
     115             :                                     SfxObjectShell which can be NULL.
     116             :                                     When it is then the application will be
     117             :                                     used */
     118             : 
     119             :     const String&       rText,  /* Text, which appears before the Statusmonitor
     120             :                                   in the status line */
     121             : 
     122             :     sal_uIntPtr               nRange, /* Max value for range  */
     123             : 
     124             :     sal_Bool                bAll,    /* Disable all documents or only the document of the ViewFram */
     125             :     sal_Bool                bWait    /* Activate the wait-Pointer initially (TRUE) */
     126             : )
     127             : 
     128             : /*  [Description]
     129             : 
     130             :     The constructor of the class SfxProgress switches the SfxObjectShell
     131             :     passed as parameter and SfxViewFrames which display this document in
     132             :     a progress mode. Ie as long as one of those SfxViewFrame instances is
     133             :     active the associated SfxDispatcher and associated Window is disabled.
     134             :     A progress-bar will be displayed in the status bar,
     135             : */
     136             : 
     137         721 : :       pImp( new SfxProgress_Impl( rText ) ),
     138             :     nVal(0),
     139        1442 :     bSuspended(sal_True)
     140             : {
     141         721 :     pImp->bRunning = sal_True;
     142         721 :     pImp->bAllowRescheduling = Application::IsInExecute();
     143             : 
     144         721 :     pImp->xObjSh = pObjSh;
     145         721 :     pImp->aText = rText;
     146         721 :     pImp->nMax = nRange;
     147         721 :     pImp->bLocked = sal_False;
     148         721 :     pImp->bWaitMode = bWait;
     149         721 :     pImp->nCreate = Get10ThSec();
     150         721 :     pImp->nNextReschedule = pImp->nCreate;
     151             :     DBG( DbgOutf( "SfxProgress: created for '%s' at %luds",
     152             :                   rText.GetBuffer(), pImp->nCreate ) );
     153         721 :     pImp->bAllDocs = bAll;
     154         721 :     pImp->pWorkWin = 0;
     155         721 :     pImp->pView = 0;
     156             : 
     157         721 :     pImp->pActiveProgress = GetActiveProgress( pObjSh );
     158         721 :     if ( pObjSh )
     159         721 :         pObjSh->SetProgress_Impl(this);
     160           0 :     else if( !pImp->pActiveProgress )
     161           0 :         SFX_APP()->SetProgress_Impl(this);
     162         721 :     Resume();
     163         721 : }
     164             : 
     165             : // -----------------------------------------------------------------------
     166             : 
     167        1442 : SfxProgress::~SfxProgress()
     168             : 
     169             : /*  [Description]
     170             : 
     171             :     The destructor of the class SfxProgress restores the old status,
     172             :     the documents are released again and the status bar shows the items again.
     173             : */
     174             : 
     175             : {
     176         721 :     Stop();
     177         721 :     if ( pImp->xStatusInd.is() )
     178         134 :         pImp->xStatusInd->end();
     179         721 :     delete pImp;
     180        1442 : }
     181             : 
     182             : // -----------------------------------------------------------------------
     183             : 
     184        1255 : void SfxProgress::Stop()
     185             : 
     186             : /*  [Description]
     187             : 
     188             :     Early Exit of <SfxProgress>.
     189             : */
     190             : 
     191             : {
     192        1255 :     if( pImp->pActiveProgress )
     193             :     {
     194           0 :         if ( pImp->xObjSh.Is() && pImp->xObjSh->GetProgress() == this )
     195           0 :             pImp->xObjSh->SetProgress_Impl(0);
     196           0 :         return;
     197             :     }
     198             : 
     199        1255 :     if ( !pImp->bRunning )
     200         534 :         return;
     201         721 :     pImp->bRunning = sal_False;
     202             :     DBG( DbgOutf( "SfxProgress: destroyed at %luds", Get10ThSec() ) );
     203             : 
     204         721 :     Suspend();
     205         721 :     if ( pImp->xObjSh.Is() )
     206         721 :         pImp->xObjSh->SetProgress_Impl(0);
     207             :     else
     208           0 :         SFX_APP()->SetProgress_Impl(0);
     209         721 :     if ( pImp->bLocked )
     210           0 :         pImp->Enable_Impl(sal_True);
     211             : }
     212             : 
     213             : // -----------------------------------------------------------------------
     214             : 
     215           0 : void SfxProgress::SetText( const OUString&  /*      new Text */)
     216             : 
     217             : /*  [Description]
     218             : 
     219             :     Changes the text that appears to the left next to progress bar.
     220             : */
     221             : 
     222             : {
     223           0 :     if( pImp->pActiveProgress ) return;
     224           0 :     if ( pImp->xStatusInd.is() )
     225             :     {
     226           0 :         pImp->xStatusInd->reset();
     227           0 :         pImp->xStatusInd->start( pImp->aText, pImp->nMax );
     228             :     }
     229             : }
     230             : 
     231             : // -----------------------------------------------------------------------
     232             : 
     233             : // Required in App data
     234             : static sal_uIntPtr nLastTime = 0;
     235             : 
     236           0 : long TimeOut_Impl( void*, void* pArgV )
     237             : {
     238           0 :     Timer *pArg = (Timer*)pArgV;
     239           0 :     if( Time::GetSystemTicks() - nLastTime > 3000 )
     240             :     {
     241           0 :         nLastTime = 0;
     242           0 :         delete pArg;
     243             :     }
     244           0 :     else pArg->Start();
     245           0 :     return 0;
     246             : }
     247             : 
     248             : // -----------------------------------------------------------------------
     249             : 
     250           4 : sal_Bool SfxProgress::SetStateText
     251             : (
     252             :     sal_uLong      nNewVal,     /* New value for the progress-bar */
     253             :     const String&  rNewVal,     /* Status as Text */
     254             :     sal_uLong      nNewRange    /* new maximum value, 0 for retaining the old */
     255             : )
     256             : 
     257             : {
     258           4 :     pImp->aStateText = rNewVal;
     259           4 :     return SetState( nNewVal, nNewRange );
     260             : }
     261             : 
     262             : // -----------------------------------------------------------------------
     263             : 
     264        5085 : sal_Bool SfxProgress::SetState
     265             : (
     266             :     sal_uLong   nNewVal,    /* new value for the progress bar */
     267             : 
     268             :     sal_uLong   nNewRange   /* new maximum value, 0 for retaining the old */
     269             : )
     270             : /*  [Description]
     271             : 
     272             :     Setting the current status, after a time delay Reschedule is called.
     273             : 
     274             :     [Return value]
     275             : 
     276             :     sal_Bool                TRUE
     277             :                         Proceed with the action
     278             : 
     279             :                         FALSE
     280             :                         Cancel action
     281             : */
     282             : 
     283             : {
     284        5085 :     if( pImp->pActiveProgress ) return sal_True;
     285             : 
     286        5085 :     nVal = nNewVal;
     287             : 
     288             :     // new Range?
     289        5085 :     if ( nNewRange && nNewRange != pImp->nMax )
     290             :     {
     291             :         DBG( DbgOutf( "SfxProgress: range changed from %lu to %lu",
     292             :                       pImp->nMax, nNewRange ) );
     293           4 :         pImp->nMax = nNewRange;
     294             :     }
     295             : 
     296        5085 :     if ( !pImp->xStatusInd.is() )
     297             :     {
     298             :         // get the active ViewFrame of the document this progress is working on
     299             :         // if it doesn't work on a document, take the current ViewFrame
     300         194 :         SfxObjectShell* pObjSh = pImp->xObjSh;
     301         194 :         pImp->pView = SfxViewFrame::Current();
     302             :         DBG_ASSERT( pImp->pView || pObjSh, "Can't make progress bar!");
     303         194 :         if ( pObjSh && ( !pImp->pView || pObjSh != pImp->pView->GetObjectShell() ) )
     304             :         {
     305             :             // current document does not belong to current ViewFrame; take it's first visible ViewFrame
     306         134 :             SfxViewFrame* pDocView = SfxViewFrame::GetFirst( pObjSh );
     307         134 :             if ( pDocView )
     308           0 :                 pImp->pView = pDocView;
     309             :             else
     310             :             {
     311             :                 // don't show status indicator for hidden documents (only valid while loading)
     312         134 :                 SfxMedium* pMedium = pObjSh->GetMedium();
     313         134 :                 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
     314         134 :                 if ( !pHiddenItem || !pHiddenItem->GetValue() )
     315             :                 {
     316             :                     {
     317         134 :                         SFX_ITEMSET_ARG( pMedium->GetItemSet(), pIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False );
     318         134 :                         Reference< XStatusIndicator > xInd;
     319         134 :                         if ( pIndicatorItem && (pIndicatorItem->GetValue()>>=xInd) )
     320          74 :                             pImp->xStatusInd = xInd;
     321             :                     }
     322             :                 }
     323             :             }
     324             :         }
     325          60 :         else if ( pImp->pView )
     326             :         {
     327          60 :             pImp->pWorkWin = SFX_APP()->GetWorkWindow_Impl( pImp->pView );
     328          60 :             if ( pImp->pWorkWin )
     329          60 :                 pImp->xStatusInd = pImp->pWorkWin->GetStatusIndicator();
     330             :         }
     331             : 
     332         194 :         if ( pImp->xStatusInd.is() )
     333             :         {
     334         134 :             pImp->xStatusInd->start( pImp->aText, pImp->nMax );
     335         134 :             pImp->pView = NULL;
     336             :         }
     337             :     }
     338             : 
     339        5085 :     if ( pImp->xStatusInd.is() )
     340             :     {
     341        5025 :         pImp->xStatusInd->setValue( nNewVal );
     342             :     }
     343             : 
     344        5085 :     return sal_True;
     345             : }
     346             : 
     347             : // -----------------------------------------------------------------------
     348             : 
     349         721 : void SfxProgress::Resume()
     350             : 
     351             : /*  [Description]
     352             : 
     353             :     Resumed the status of the display after an interrupt.
     354             : 
     355             :     [Cross-reference]
     356             : 
     357             :     <SfxProgress::Suspend()>
     358             : */
     359             : 
     360             : {
     361        1442 :     if( pImp->pActiveProgress ) return;
     362         721 :     if ( bSuspended )
     363             :     {
     364             :         DBG( DbgOutf( "SfxProgress: resumed" ) );
     365         721 :         if ( pImp->xStatusInd.is() )
     366             :         {
     367           0 :             pImp->xStatusInd->start( pImp->aText, pImp->nMax );
     368           0 :             pImp->xStatusInd->setValue( nVal );
     369             :         }
     370             : 
     371         721 :         if ( pImp->bWaitMode )
     372             :         {
     373         721 :             if ( pImp->xObjSh.Is() && !pImp->bAllDocs )
     374             :             {
     375        1338 :                 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImp->xObjSh);
     376             :                         pFrame;
     377         617 :                         pFrame = SfxViewFrame::GetNext( *pFrame, pImp->xObjSh ) )
     378         617 :                     pFrame->GetWindow().EnterWait();
     379             :             }
     380             :         }
     381             : 
     382         721 :         if ( pImp->xObjSh )
     383             :         {
     384         721 :             SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImp->xObjSh);
     385         721 :             if ( pFrame )
     386         617 :                 pFrame->GetBindings().ENTERREGISTRATIONS();
     387             :         }
     388             : 
     389         721 :         bSuspended = sal_False;
     390             :     }
     391             : }
     392             : 
     393             : // -----------------------------------------------------------------------
     394             : 
     395         721 : void SfxProgress::Suspend()
     396             : 
     397             : /*  [Description]
     398             : 
     399             :     Interrupts the status of the display
     400             : 
     401             :     [Cross-reference]
     402             : 
     403             :     <SfxProgress::Resume()>
     404             : */
     405             : 
     406             : {
     407        1442 :     if( pImp->pActiveProgress ) return;
     408         721 :     if ( !bSuspended )
     409             :     {
     410             :         DBG( DbgOutf( "SfxProgress: suspended" ) );
     411         721 :         bSuspended = sal_True;
     412             : 
     413         721 :         if ( pImp->xStatusInd.is() )
     414             :         {
     415         134 :             pImp->xStatusInd->reset();
     416             :         }
     417             : 
     418         721 :         if ( pImp->xObjSh.Is() && !pImp->bAllDocs )
     419             :         {
     420        1338 :             for ( SfxViewFrame *pFrame =
     421         721 :                     SfxViewFrame::GetFirst(pImp->xObjSh);
     422             :                     pFrame;
     423         617 :                     pFrame = SfxViewFrame::GetNext( *pFrame, pImp->xObjSh ) )
     424         617 :                 pFrame->GetWindow().LeaveWait();
     425             :         }
     426         721 :         if ( pImp->xObjSh.Is() )
     427             :         {
     428         721 :             SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImp->xObjSh);
     429         721 :             if ( pFrame )
     430         617 :                 pFrame->GetBindings().LEAVEREGISTRATIONS();
     431             :         }
     432             :     }
     433             : }
     434             : 
     435             : // -----------------------------------------------------------------------
     436             : 
     437           0 : void SfxProgress::UnLock()
     438             : {
     439           0 :     if( pImp->pActiveProgress ) return;
     440           0 :     if ( !pImp->bLocked )
     441           0 :         return;
     442             : 
     443             :     DBG( DbgOutf( "SfxProgress: unlocked" ) );
     444           0 :     pImp->bLocked = sal_False;
     445           0 :     pImp->Enable_Impl(sal_True);
     446             : }
     447             : 
     448             : // -----------------------------------------------------------------------
     449             : 
     450        2096 : void SfxProgress::Reschedule()
     451             : 
     452             : /*  [Description]
     453             : 
     454             :     Reschedule, callable from the outside
     455             : */
     456             : 
     457             : {
     458             :     SFX_STACK(SfxProgress::Reschedule);
     459             : 
     460        4192 :     if( pImp->pActiveProgress ) return;
     461        2096 :     SfxApplication* pApp = SFX_APP();
     462        2096 :     if ( pImp->bLocked && 0 == pApp->Get_Impl()->nRescheduleLocks )
     463             :     {
     464           0 :         SfxAppData_Impl *pAppData = pApp->Get_Impl();
     465           0 :         ++pAppData->nInReschedule;
     466           0 :         Application::Reschedule();
     467           0 :         --pAppData->nInReschedule;
     468             :     }
     469             : }
     470             : 
     471             : // -----------------------------------------------------------------------
     472             : 
     473        3034 : SfxProgress* SfxProgress::GetActiveProgress
     474             : (
     475             :     SfxObjectShell* pDocSh        /*  the <SfxObjectShell>, which should be
     476             :                                       queried after a current <SfxProgress>,
     477             :                                       or 0 if an current SfxProgress for the
     478             :                                       entire application should be obtained.
     479             :                                       The pointer only needs at the time of
     480             :                                       the call to be valid.
     481             :                                   */
     482             : )
     483             : 
     484             : /*  [Description]
     485             : 
     486             :     This method is used to check whether and which <SfxProgress> is currently
     487             :     active for a specific instance of SfxObjectShell or even an entire
     488             :     application. This can for example be used to check for Time-Out-Events, etc.
     489             : 
     490             :     Instead of a pointer to the SfxProgress the SfxObjectShell may be
     491             :     pointed at the SfxProgress of the application, with the query
     492             :     'SfxProgress:: GetActiveProgress (pMyDocSh)' thus the current
     493             :     SfxProgress of 'pMyDocSh' is delivered, otherwise the SfxProgress of
     494             :     the application or a 0-pointer.
     495             : 
     496             :     [Note]
     497             : 
     498             :     If no SfxProgress is running in the application and also not at the
     499             :     specified SfxObjectShell, then this method will always return 0,
     500             :     even if one SfxProgress runs on another SfxObjectShell.
     501             : 
     502             :     [Cross-reference]
     503             : 
     504             :     <SfxApplication::GetProgress()const>
     505             :     <SfxObjectShell::GetProgress()const>
     506             : */
     507             : 
     508             : {
     509        3034 :     if ( !SfxApplication::Get() )
     510           0 :         return 0;
     511             : 
     512        3034 :     SfxProgress *pProgress = 0;
     513        3034 :     if ( pDocSh )
     514        2752 :         pProgress = pDocSh->GetProgress();
     515        3034 :     if ( !pProgress )
     516        3029 :         pProgress = SFX_APP()->GetProgress();
     517        3034 :     return pProgress;
     518             : }
     519             : 
     520             : // -----------------------------------------------------------------------
     521             : 
     522          54 : void SfxProgress::EnterLock()
     523             : {
     524          54 :     SFX_APP()->Get_Impl()->nRescheduleLocks++;
     525          54 : }
     526             : 
     527             : // -----------------------------------------------------------------------
     528             : 
     529          54 : void SfxProgress::LeaveLock()
     530             : {
     531          54 :     SfxAppData_Impl *pImp = SFX_APP()->Get_Impl();
     532             :     DBG_ASSERT( 0 != pImp->nRescheduleLocks, "SFxProgress::LeaveLock but no locks" );
     533          54 :     pImp->nRescheduleLocks--;
     534         462 : }
     535             : 
     536             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10