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

Generated by: LCOV version 1.11