1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sfx2/progress.hxx>
22 #include <com/sun/star/uno/Reference.hxx>
23 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
25 #include <basic/sbx.hxx>
27 #include <svl/eitem.hxx>
28 #include <tools/time.hxx>
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>
43 #include <sfx2/msg.hxx>
44 #include "sfxslots.hxx"
45 #include "sfxbasecontroller_internal.hxx"
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::frame
;
50 using namespace ::com::sun::star::task
;
52 struct SfxProgress_Impl
54 Reference
< XStatusIndicator
> xStatusInd
;
55 OUString aText
, aStateText
;
58 clock_t nNextReschedule
;
59 bool bLocked
, bAllDocs
;
61 bool bAllowRescheduling
;
64 SfxProgress
* pActiveProgress
;
65 SfxObjectShellRef xObjSh
;
66 SfxWorkWindow
* pWorkWin
;
69 SfxProgress_Impl( const OUString
& );
70 void Enable_Impl( bool );
76 void SfxProgress_Impl::Enable_Impl( bool bEnable
)
78 SfxObjectShell
* pDoc
= bAllDocs
? NULL
: (SfxObjectShell
*) xObjSh
;
79 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst(pDoc
);
82 pFrame
->Enable(bEnable
);
83 pFrame
->GetDispatcher()->Lock( !bEnable
);
84 pFrame
= SfxViewFrame::GetNext(*pFrame
, pDoc
);
89 pView
->Enable( bEnable
);
90 pView
->GetDispatcher()->Lock( !bEnable
);
94 SfxGetpApp()->GetAppDispatcher_Impl()->Lock( !bEnable
);
99 SfxProgress_Impl::SfxProgress_Impl( const OUString
&/*rTitle*/ )
106 , bAllowRescheduling(false)
116 SfxProgress::SfxProgress
118 SfxObjectShell
* pObjSh
, /* The action is performed on the
119 SfxObjectShell which can be NULL.
120 When it is then the application will be
123 const OUString
& rText
, /* Text, which appears before the Statusmonitor
124 in the status line */
126 sal_uIntPtr nRange
, /* Max value for range */
128 bool bAll
, /* Disable all documents or only the document of the ViewFram */
129 bool bWait
/* Activate the wait-Pointer initially (TRUE) */
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,
141 : pImp( new SfxProgress_Impl( rText
) ),
145 pImp
->bRunning
= true;
146 pImp
->bAllowRescheduling
= Application::IsInExecute();
148 pImp
->xObjSh
= pObjSh
;
151 pImp
->bLocked
= false;
152 pImp
->bWaitMode
= bWait
;
153 pImp
->nCreate
= Get10ThSec();
154 pImp
->nNextReschedule
= pImp
->nCreate
;
157 "SfxProgress: created for '" << rText
<< "' at " << pImp
->nCreate
159 pImp
->bAllDocs
= bAll
;
163 pImp
->pActiveProgress
= GetActiveProgress( pObjSh
);
165 pObjSh
->SetProgress_Impl(this);
166 else if( !pImp
->pActiveProgress
)
167 SfxGetpApp()->SetProgress_Impl(this);
173 SfxProgress::~SfxProgress()
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.
183 if ( pImp
->xStatusInd
.is() )
184 pImp
->xStatusInd
->end();
190 void SfxProgress::Stop()
194 Early Exit of <SfxProgress>.
198 if( pImp
->pActiveProgress
)
200 if ( pImp
->xObjSh
.Is() && pImp
->xObjSh
->GetProgress() == this )
201 pImp
->xObjSh
->SetProgress_Impl(0);
205 if ( !pImp
->bRunning
)
207 pImp
->bRunning
= false;
209 "sfx.bastyp", "SfxProgress: destroyed at " << Get10ThSec() << "ds");
212 if ( pImp
->xObjSh
.Is() )
213 pImp
->xObjSh
->SetProgress_Impl(0);
215 SfxGetpApp()->SetProgress_Impl(0);
217 pImp
->Enable_Impl(true);
220 bool SfxProgress::SetStateText
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 */
228 pImp
->aStateText
= rNewVal
;
229 return SetState( nNewVal
, nNewRange
);
232 bool SfxProgress::SetState
234 sal_uLong nNewVal
, /* new value for the progress bar */
236 sal_uLong nNewRange
/* new maximum value, 0 for retaining the old */
240 Setting the current status, after a time delay Reschedule is called.
245 Proceed with the action
252 if( pImp
->pActiveProgress
) return true;
257 if ( nNewRange
&& nNewRange
!= pImp
->nMax
)
261 "SfxProgress: range changed from " << pImp
->nMax
<< " to "
263 pImp
->nMax
= nNewRange
;
266 if ( !pImp
->xStatusInd
.is() )
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 SfxObjectShell
* pObjSh
= pImp
->xObjSh
;
271 pImp
->pView
= SfxViewFrame::Current();
272 DBG_ASSERT( pImp
->pView
|| pObjSh
, "Can't make progress bar!");
273 if ( pObjSh
&& ( !pImp
->pView
|| pObjSh
!= pImp
->pView
->GetObjectShell() ) )
275 // current document does not belong to current ViewFrame; take it's first visible ViewFrame
276 SfxViewFrame
* pDocView
= SfxViewFrame::GetFirst( pObjSh
);
278 pImp
->pView
= pDocView
;
281 // don't show status indicator for hidden documents (only valid while loading)
282 SfxMedium
* pMedium
= pObjSh
->GetMedium();
283 SFX_ITEMSET_ARG( pMedium
->GetItemSet(), pHiddenItem
, SfxBoolItem
, SID_HIDDEN
, false );
284 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
287 SFX_ITEMSET_ARG( pMedium
->GetItemSet(), pIndicatorItem
, SfxUnoAnyItem
, SID_PROGRESS_STATUSBAR_CONTROL
, false );
288 Reference
< XStatusIndicator
> xInd
;
289 if ( pIndicatorItem
&& (pIndicatorItem
->GetValue()>>=xInd
) )
290 pImp
->xStatusInd
= xInd
;
295 else if ( pImp
->pView
)
297 pImp
->pWorkWin
= SfxGetpApp()->GetWorkWindow_Impl( pImp
->pView
);
298 if ( pImp
->pWorkWin
)
299 pImp
->xStatusInd
= pImp
->pWorkWin
->GetStatusIndicator();
302 if ( pImp
->xStatusInd
.is() )
304 pImp
->xStatusInd
->start( pImp
->aText
, pImp
->nMax
);
309 if ( pImp
->xStatusInd
.is() )
311 pImp
->xStatusInd
->setValue( nNewVal
);
319 void SfxProgress::Resume()
323 Resumed the status of the display after an interrupt.
327 <SfxProgress::Suspend()>
331 if( pImp
->pActiveProgress
) return;
334 SAL_INFO("sfx.bastyp", "SfxProgress: resumed");
335 if ( pImp
->xStatusInd
.is() )
337 pImp
->xStatusInd
->start( pImp
->aText
, pImp
->nMax
);
338 pImp
->xStatusInd
->setValue( nVal
);
341 if ( pImp
->bWaitMode
)
343 if ( pImp
->xObjSh
.Is() && !pImp
->bAllDocs
)
345 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst(pImp
->xObjSh
);
347 pFrame
= SfxViewFrame::GetNext( *pFrame
, pImp
->xObjSh
) )
348 pFrame
->GetWindow().EnterWait();
354 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst(pImp
->xObjSh
);
356 pFrame
->GetBindings().ENTERREGISTRATIONS();
365 void SfxProgress::Suspend()
369 Interrupts the status of the display
373 <SfxProgress::Resume()>
377 if( pImp
->pActiveProgress
) return;
380 SAL_INFO("sfx.bastyp", "SfxProgress: suspended");
383 if ( pImp
->xStatusInd
.is() )
385 pImp
->xStatusInd
->reset();
388 if ( pImp
->xObjSh
.Is() && !pImp
->bAllDocs
)
390 for ( SfxViewFrame
*pFrame
=
391 SfxViewFrame::GetFirst(pImp
->xObjSh
);
393 pFrame
= SfxViewFrame::GetNext( *pFrame
, pImp
->xObjSh
) )
394 pFrame
->GetWindow().LeaveWait();
396 if ( pImp
->xObjSh
.Is() )
398 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst(pImp
->xObjSh
);
400 pFrame
->GetBindings().LEAVEREGISTRATIONS();
407 void SfxProgress::UnLock()
409 if( pImp
->pActiveProgress
) return;
410 if ( !pImp
->bLocked
)
413 SAL_INFO("sfx.bastyp", "SfxProgress: unlocked");
414 pImp
->bLocked
= false;
415 pImp
->Enable_Impl(true);
420 void SfxProgress::Reschedule()
424 Reschedule, callable from the outside
428 SFX_STACK(SfxProgress::Reschedule
);
430 if( pImp
->pActiveProgress
) return;
431 SfxApplication
* pApp
= SfxGetpApp();
432 if ( pImp
->bLocked
&& 0 == pApp
->Get_Impl()->nRescheduleLocks
)
434 SfxAppData_Impl
*pAppData
= pApp
->Get_Impl();
435 ++pAppData
->nInReschedule
;
436 Application::Reschedule();
437 --pAppData
->nInReschedule
;
443 SfxProgress
* SfxProgress::GetActiveProgress
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.
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.
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.
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.
474 <SfxApplication::GetProgress()const>
475 <SfxObjectShell::GetProgress()const>
479 if ( !SfxApplication::Get() )
482 SfxProgress
*pProgress
= 0;
484 pProgress
= pDocSh
->GetProgress();
486 pProgress
= SfxGetpApp()->GetProgress();
492 void SfxProgress::EnterLock()
494 SfxGetpApp()->Get_Impl()->nRescheduleLocks
++;
499 void SfxProgress::LeaveLock()
501 SfxAppData_Impl
*pImp
= SfxGetpApp()->Get_Impl();
502 DBG_ASSERT( 0 != pImp
->nRescheduleLocks
, "SFxProgress::LeaveLock but no locks" );
503 pImp
->nRescheduleLocks
--;
506 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */