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

Generated by: LCOV version 1.10