LCOV - code coverage report
Current view: top level - sfx2/source/bastyp - progress.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 119 157 75.8 %
Date: 2014-11-03 Functions: 16 19 84.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             : #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        5356 : 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 : (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        5356 : 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        5356 :     , pView(0)
     111             : {
     112        5356 : }
     113             : 
     114             : 
     115             : 
     116        5356 : 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        5356 : :       pImp( new SfxProgress_Impl( rText ) ),
     142             :     nVal(0),
     143       10712 :     bSuspended(true)
     144             : {
     145        5356 :     pImp->bRunning = true;
     146        5356 :     pImp->bAllowRescheduling = Application::IsInExecute();
     147             : 
     148        5356 :     pImp->xObjSh = pObjSh;
     149        5356 :     pImp->aText = rText;
     150        5356 :     pImp->nMax = nRange;
     151        5356 :     pImp->bLocked = false;
     152        5356 :     pImp->bWaitMode = bWait;
     153        5356 :     pImp->nCreate = Get10ThSec();
     154        5356 :     pImp->nNextReschedule = pImp->nCreate;
     155             :     SAL_INFO(
     156             :         "sfx.bastyp",
     157             :         "SfxProgress: created for '" << rText << "' at " << pImp->nCreate
     158             :             << "ds");
     159        5356 :     pImp->bAllDocs = bAll;
     160        5356 :     pImp->pWorkWin = 0;
     161        5356 :     pImp->pView = 0;
     162             : 
     163        5356 :     pImp->pActiveProgress = GetActiveProgress( pObjSh );
     164        5356 :     if ( pObjSh )
     165        5356 :         pObjSh->SetProgress_Impl(this);
     166           0 :     else if( !pImp->pActiveProgress )
     167           0 :         SfxGetpApp()->SetProgress_Impl(this);
     168        5356 :     Resume();
     169        5356 : }
     170             : 
     171             : 
     172             : 
     173       10708 : 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        5356 :     Stop();
     183        5356 :     if ( pImp->xStatusInd.is() )
     184         878 :         pImp->xStatusInd->end();
     185        5356 :     delete pImp;
     186       10708 : }
     187             : 
     188             : 
     189             : 
     190       10286 : void SfxProgress::Stop()
     191             : 
     192             : /*  [Description]
     193             : 
     194             :     Early Exit of <SfxProgress>.
     195             : */
     196             : 
     197             : {
     198       10286 :     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       10286 :     if ( !pImp->bRunning )
     206        4930 :         return;
     207        5356 :     pImp->bRunning = false;
     208             :     SAL_INFO(
     209             :         "sfx.bastyp", "SfxProgress: destroyed at " << Get10ThSec() << "ds");
     210             : 
     211        5356 :     Suspend();
     212        5356 :     if ( pImp->xObjSh.Is() )
     213        5356 :         pImp->xObjSh->SetProgress_Impl(0);
     214             :     else
     215           0 :         SfxGetpApp()->SetProgress_Impl(0);
     216        5356 :     if ( pImp->bLocked )
     217           0 :         pImp->Enable_Impl(true);
     218             : }
     219             : 
     220             : 
     221             : 
     222           0 : void SfxProgress::SetText( const OUString&  /*      new Text */)
     223             : 
     224             : /*  [Description]
     225             : 
     226             :     Changes the text that appears to the left next to progress bar.
     227             : */
     228             : 
     229             : {
     230           0 :     if( pImp->pActiveProgress ) return;
     231           0 :     if ( pImp->xStatusInd.is() )
     232             :     {
     233           0 :         pImp->xStatusInd->reset();
     234           0 :         pImp->xStatusInd->start( pImp->aText, pImp->nMax );
     235             :     }
     236             : }
     237             : 
     238           8 : bool SfxProgress::SetStateText
     239             : (
     240             :     sal_uLong       nNewVal,     /* New value for the progress-bar */
     241             :     const OUString& rNewVal,     /* Status as Text */
     242             :     sal_uLong       nNewRange    /* new maximum value, 0 for retaining the old */
     243             : )
     244             : 
     245             : {
     246           8 :     pImp->aStateText = rNewVal;
     247           8 :     return SetState( nNewVal, nNewRange );
     248             : }
     249             : 
     250             : 
     251             : 
     252       14570 : bool SfxProgress::SetState
     253             : (
     254             :     sal_uLong   nNewVal,    /* new value for the progress bar */
     255             : 
     256             :     sal_uLong   nNewRange   /* new maximum value, 0 for retaining the old */
     257             : )
     258             : /*  [Description]
     259             : 
     260             :     Setting the current status, after a time delay Reschedule is called.
     261             : 
     262             :     [Return value]
     263             : 
     264             :     bool                TRUE
     265             :                         Proceed with the action
     266             : 
     267             :                         FALSE
     268             :                         Cancel action
     269             : */
     270             : 
     271             : {
     272       14570 :     if( pImp->pActiveProgress ) return true;
     273             : 
     274       14570 :     nVal = nNewVal;
     275             : 
     276             :     // new Range?
     277       14570 :     if ( nNewRange && nNewRange != pImp->nMax )
     278             :     {
     279             :         SAL_INFO(
     280             :             "sfx.bastyp",
     281             :             "SfxProgress: range changed from " << pImp->nMax << " to "
     282             :                 << nNewRange);
     283          36 :         pImp->nMax = nNewRange;
     284             :     }
     285             : 
     286       14570 :     if ( !pImp->xStatusInd.is() )
     287             :     {
     288             :         // get the active ViewFrame of the document this progress is working on
     289             :         // if it doesn't work on a document, take the current ViewFrame
     290        1250 :         SfxObjectShell* pObjSh = pImp->xObjSh;
     291        1250 :         pImp->pView = SfxViewFrame::Current();
     292             :         DBG_ASSERT( pImp->pView || pObjSh, "Can't make progress bar!");
     293        1250 :         if ( pObjSh && ( !pImp->pView || pObjSh != pImp->pView->GetObjectShell() ) )
     294             :         {
     295             :             // current document does not belong to current ViewFrame; take it's first visible ViewFrame
     296         612 :             SfxViewFrame* pDocView = SfxViewFrame::GetFirst( pObjSh );
     297         612 :             if ( pDocView )
     298           2 :                 pImp->pView = pDocView;
     299             :             else
     300             :             {
     301             :                 // don't show status indicator for hidden documents (only valid while loading)
     302         610 :                 SfxMedium* pMedium = pObjSh->GetMedium();
     303         610 :                 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, false );
     304         610 :                 if ( !pHiddenItem || !pHiddenItem->GetValue() )
     305             :                 {
     306             :                     {
     307         534 :                         SFX_ITEMSET_ARG( pMedium->GetItemSet(), pIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, false );
     308         534 :                         Reference< XStatusIndicator > xInd;
     309         534 :                         if ( pIndicatorItem && (pIndicatorItem->GetValue()>>=xInd) )
     310         240 :                             pImp->xStatusInd = xInd;
     311             :                     }
     312             :                 }
     313             :             }
     314             :         }
     315         638 :         else if ( pImp->pView )
     316             :         {
     317         638 :             pImp->pWorkWin = SfxGetpApp()->GetWorkWindow_Impl( pImp->pView );
     318         638 :             if ( pImp->pWorkWin )
     319         638 :                 pImp->xStatusInd = pImp->pWorkWin->GetStatusIndicator();
     320             :         }
     321             : 
     322        1250 :         if ( pImp->xStatusInd.is() )
     323             :         {
     324         878 :             pImp->xStatusInd->start( pImp->aText, pImp->nMax );
     325         878 :             pImp->pView = NULL;
     326             :         }
     327             :     }
     328             : 
     329       14570 :     if ( pImp->xStatusInd.is() )
     330             :     {
     331       14198 :         pImp->xStatusInd->setValue( nNewVal );
     332             :     }
     333             : 
     334       14570 :     return true;
     335             : }
     336             : 
     337             : 
     338             : 
     339        5356 : void SfxProgress::Resume()
     340             : 
     341             : /*  [Description]
     342             : 
     343             :     Resumed the status of the display after an interrupt.
     344             : 
     345             :     [Cross-reference]
     346             : 
     347             :     <SfxProgress::Suspend()>
     348             : */
     349             : 
     350             : {
     351       10712 :     if( pImp->pActiveProgress ) return;
     352        5356 :     if ( bSuspended )
     353             :     {
     354             :         SAL_INFO("sfx.bastyp", "SfxProgress: resumed");
     355        5356 :         if ( pImp->xStatusInd.is() )
     356             :         {
     357           0 :             pImp->xStatusInd->start( pImp->aText, pImp->nMax );
     358           0 :             pImp->xStatusInd->setValue( nVal );
     359             :         }
     360             : 
     361        5356 :         if ( pImp->bWaitMode )
     362             :         {
     363        5356 :             if ( pImp->xObjSh.Is() && !pImp->bAllDocs )
     364             :             {
     365       10274 :                 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImp->xObjSh);
     366             :                         pFrame;
     367        4918 :                         pFrame = SfxViewFrame::GetNext( *pFrame, pImp->xObjSh ) )
     368        4918 :                     pFrame->GetWindow().EnterWait();
     369             :             }
     370             :         }
     371             : 
     372        5356 :         if ( pImp->xObjSh )
     373             :         {
     374        5356 :             SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImp->xObjSh);
     375        5356 :             if ( pFrame )
     376        4918 :                 pFrame->GetBindings().ENTERREGISTRATIONS();
     377             :         }
     378             : 
     379        5356 :         bSuspended = false;
     380             :     }
     381             : }
     382             : 
     383             : 
     384             : 
     385        5356 : void SfxProgress::Suspend()
     386             : 
     387             : /*  [Description]
     388             : 
     389             :     Interrupts the status of the display
     390             : 
     391             :     [Cross-reference]
     392             : 
     393             :     <SfxProgress::Resume()>
     394             : */
     395             : 
     396             : {
     397       10712 :     if( pImp->pActiveProgress ) return;
     398        5356 :     if ( !bSuspended )
     399             :     {
     400             :         SAL_INFO("sfx.bastyp", "SfxProgress: suspended");
     401        5356 :         bSuspended = true;
     402             : 
     403        5356 :         if ( pImp->xStatusInd.is() )
     404             :         {
     405         878 :             pImp->xStatusInd->reset();
     406             :         }
     407             : 
     408        5356 :         if ( pImp->xObjSh.Is() && !pImp->bAllDocs )
     409             :         {
     410       10274 :             for ( SfxViewFrame *pFrame =
     411        5356 :                     SfxViewFrame::GetFirst(pImp->xObjSh);
     412             :                     pFrame;
     413        4918 :                     pFrame = SfxViewFrame::GetNext( *pFrame, pImp->xObjSh ) )
     414        4918 :                 pFrame->GetWindow().LeaveWait();
     415             :         }
     416        5356 :         if ( pImp->xObjSh.Is() )
     417             :         {
     418        5356 :             SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImp->xObjSh);
     419        5356 :             if ( pFrame )
     420        4918 :                 pFrame->GetBindings().LEAVEREGISTRATIONS();
     421             :         }
     422             :     }
     423             : }
     424             : 
     425             : 
     426             : 
     427           0 : void SfxProgress::UnLock()
     428             : {
     429           0 :     if( pImp->pActiveProgress ) return;
     430           0 :     if ( !pImp->bLocked )
     431           0 :         return;
     432             : 
     433             :     SAL_INFO("sfx.bastyp", "SfxProgress: unlocked");
     434           0 :     pImp->bLocked = false;
     435           0 :     pImp->Enable_Impl(true);
     436             : }
     437             : 
     438             : 
     439             : 
     440      113188 : void SfxProgress::Reschedule()
     441             : 
     442             : /*  [Description]
     443             : 
     444             :     Reschedule, callable from the outside
     445             : */
     446             : 
     447             : {
     448             :     SFX_STACK(SfxProgress::Reschedule);
     449             : 
     450      226376 :     if( pImp->pActiveProgress ) return;
     451      113188 :     SfxApplication* pApp = SfxGetpApp();
     452      113188 :     if ( pImp->bLocked && 0 == pApp->Get_Impl()->nRescheduleLocks )
     453             :     {
     454           0 :         SfxAppData_Impl *pAppData = pApp->Get_Impl();
     455           0 :         ++pAppData->nInReschedule;
     456           0 :         Application::Reschedule();
     457           0 :         --pAppData->nInReschedule;
     458             :     }
     459             : }
     460             : 
     461             : 
     462             : 
     463       14507 : SfxProgress* SfxProgress::GetActiveProgress
     464             : (
     465             :     SfxObjectShell* pDocSh        /*  the <SfxObjectShell>, which should be
     466             :                                       queried after a current <SfxProgress>,
     467             :                                       or 0 if an current SfxProgress for the
     468             :                                       entire application should be obtained.
     469             :                                       The pointer only needs at the time of
     470             :                                       the call to be valid.
     471             :                                   */
     472             : )
     473             : 
     474             : /*  [Description]
     475             : 
     476             :     This method is used to check whether and which <SfxProgress> is currently
     477             :     active for a specific instance of SfxObjectShell or even an entire
     478             :     application. This can for example be used to check for Time-Out-Events, etc.
     479             : 
     480             :     Instead of a pointer to the SfxProgress the SfxObjectShell may be
     481             :     pointed at the SfxProgress of the application, with the query
     482             :     'SfxProgress:: GetActiveProgress (pMyDocSh)' thus the current
     483             :     SfxProgress of 'pMyDocSh' is delivered, otherwise the SfxProgress of
     484             :     the application or a 0-pointer.
     485             : 
     486             :     [Note]
     487             : 
     488             :     If no SfxProgress is running in the application and also not at the
     489             :     specified SfxObjectShell, then this method will always return 0,
     490             :     even if one SfxProgress runs on another SfxObjectShell.
     491             : 
     492             :     [Cross-reference]
     493             : 
     494             :     <SfxApplication::GetProgress()const>
     495             :     <SfxObjectShell::GetProgress()const>
     496             : */
     497             : 
     498             : {
     499       14507 :     if ( !SfxApplication::Get() )
     500           0 :         return 0;
     501             : 
     502       14507 :     SfxProgress *pProgress = 0;
     503       14507 :     if ( pDocSh )
     504       13647 :         pProgress = pDocSh->GetProgress();
     505       14507 :     if ( !pProgress )
     506       14212 :         pProgress = SfxGetpApp()->GetProgress();
     507       14507 :     return pProgress;
     508             : }
     509             : 
     510             : 
     511             : 
     512         287 : void SfxProgress::EnterLock()
     513             : {
     514         287 :     SfxGetpApp()->Get_Impl()->nRescheduleLocks++;
     515         287 : }
     516             : 
     517             : 
     518             : 
     519         287 : void SfxProgress::LeaveLock()
     520             : {
     521         287 :     SfxAppData_Impl *pImp = SfxGetpApp()->Get_Impl();
     522             :     DBG_ASSERT( 0 != pImp->nRescheduleLocks, "SFxProgress::LeaveLock but no locks" );
     523         287 :     pImp->nRescheduleLocks--;
     524        1238 : }
     525             : 
     526             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10