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

Generated by: LCOV version 1.10