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 <svl/eitem.hxx>
26 #include <tools/debug.hxx>
27 #include <sal/log.hxx>
29 #include <appdata.hxx>
30 #include <sfx2/bindings.hxx>
31 #include <sfx2/frame.hxx>
32 #include <sfx2/viewfrm.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <sfx2/app.hxx>
35 #include <sfxtypes.hxx>
36 #include <sfx2/docfile.hxx>
37 #include <sfx2/sfxsids.hrc>
38 #include <workwin.hxx>
39 #include <sfxbasecontroller_internal.hxx>
42 using namespace ::com::sun::star::uno
;
43 using namespace ::com::sun::star::task
;
45 struct SfxProgress_Impl
47 Reference
< XStatusIndicator
> xStatusInd
;
54 SfxProgress
* pActiveProgress
;
55 SfxObjectShellRef xObjSh
;
56 SfxWorkWindow
* pWorkWin
;
59 explicit SfxProgress_Impl();
62 SfxProgress_Impl::SfxProgress_Impl()
67 , pActiveProgress(nullptr)
74 SfxProgress::SfxProgress
76 SfxObjectShell
* pObjSh
, /* The action is performed on the
77 SfxObjectShell which can be NULL.
78 When it is then the application will be
81 const OUString
& rText
, /* Text, which appears before the Statusmonitor
84 sal_uInt32 nRange
, /* Max value for range */
86 bool bWait
/* Activate the wait-Pointer initially (TRUE) */
91 The constructor of the class SfxProgress switches the SfxObjectShell
92 passed as parameter and SfxViewFrames which display this document in
93 a progress mode. Ie as long as one of those SfxViewFrame instances is
94 active the associated SfxDispatcher and associated Window is disabled.
95 A progress-bar will be displayed in the status bar,
98 : pImpl( new SfxProgress_Impl
),
102 pImpl
->bRunning
= true;
104 pImpl
->xObjSh
= pObjSh
;
105 pImpl
->aText
= rText
;
106 pImpl
->nMax
= nRange
;
107 pImpl
->bWaitMode
= bWait
;
108 pImpl
->nCreate
= Get10ThSec();
111 "SfxProgress: created for '" << rText
<< "' at " << pImpl
->nCreate
113 pImpl
->pWorkWin
= nullptr;
114 pImpl
->pView
= nullptr;
116 pImpl
->pActiveProgress
= GetActiveProgress( pObjSh
);
118 pObjSh
->SetProgress_Impl(this);
119 else if( !pImpl
->pActiveProgress
)
120 SfxGetpApp()->SetProgress_Impl(this);
125 SfxProgress::~SfxProgress()
129 The destructor of the class SfxProgress restores the old status,
130 the documents are released again and the status bar shows the items again.
135 if ( pImpl
->xStatusInd
.is() )
136 pImpl
->xStatusInd
->end();
140 void SfxProgress::Stop()
144 Early Exit of <SfxProgress>.
148 if( pImpl
->pActiveProgress
)
150 if ( pImpl
->xObjSh
.is() && pImpl
->xObjSh
->GetProgress() == this )
151 pImpl
->xObjSh
->SetProgress_Impl(nullptr);
155 if ( !pImpl
->bRunning
)
157 pImpl
->bRunning
= false;
159 "sfx.bastyp", "SfxProgress: destroyed at " << Get10ThSec() << "ds");
162 if ( pImpl
->xObjSh
.is() )
163 pImpl
->xObjSh
->SetProgress_Impl(nullptr);
165 SfxGetpApp()->SetProgress_Impl(nullptr);
168 void SfxProgress::SetState
170 sal_uInt32 nNewVal
, /* new value for the progress bar */
172 sal_uInt32 nNewRange
/* new maximum value, 0 for retaining the old */
176 Setting the current status, after a time delay Reschedule is called.
180 if( pImpl
->pActiveProgress
) return;
185 if ( nNewRange
&& nNewRange
!= pImpl
->nMax
)
189 "SfxProgress: range changed from " << pImpl
->nMax
<< " to "
191 pImpl
->nMax
= nNewRange
;
194 if ( !pImpl
->xStatusInd
.is() )
196 // get the active ViewFrame of the document this progress is working on
197 // if it doesn't work on a document, take the current ViewFrame
198 SfxObjectShell
* pObjSh
= pImpl
->xObjSh
.get();
199 pImpl
->pView
= SfxViewFrame::Current();
200 DBG_ASSERT( pImpl
->pView
|| pObjSh
, "Can't make progress bar!");
201 if ( pObjSh
&& ( !pImpl
->pView
|| pObjSh
!= pImpl
->pView
->GetObjectShell() ) )
203 // current document does not belong to current ViewFrame; take it's first visible ViewFrame
204 SfxViewFrame
* pDocView
= SfxViewFrame::GetFirst( pObjSh
);
206 pImpl
->pView
= pDocView
;
209 // don't show status indicator for hidden documents (only valid while loading)
210 SfxMedium
* pMedium
= pObjSh
->GetMedium();
211 const SfxBoolItem
* pHiddenItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_HIDDEN
, false);
212 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
214 const SfxUnoAnyItem
* pIndicatorItem
= SfxItemSet::GetItem
<SfxUnoAnyItem
>(pMedium
->GetItemSet(), SID_PROGRESS_STATUSBAR_CONTROL
, false);
215 Reference
< XStatusIndicator
> xInd
;
216 if ( pIndicatorItem
&& (pIndicatorItem
->GetValue()>>=xInd
) )
217 pImpl
->xStatusInd
= xInd
;
221 else if ( pImpl
->pView
)
223 pImpl
->pWorkWin
= SfxGetpApp()->GetWorkWindow_Impl( pImpl
->pView
);
224 if ( pImpl
->pWorkWin
)
225 pImpl
->xStatusInd
= pImpl
->pWorkWin
->GetStatusIndicator();
228 if ( pImpl
->xStatusInd
.is() )
230 pImpl
->xStatusInd
->start( pImpl
->aText
, pImpl
->nMax
);
231 pImpl
->pView
= nullptr;
235 if ( pImpl
->xStatusInd
.is() )
237 pImpl
->xStatusInd
->setValue( nNewVal
);
242 void SfxProgress::Resume()
246 Resumed the status of the display after an interrupt.
250 <SfxProgress::Suspend()>
254 if( pImpl
->pActiveProgress
) return;
258 SAL_INFO("sfx.bastyp", "SfxProgress: resumed");
259 if ( pImpl
->xStatusInd
.is() )
261 pImpl
->xStatusInd
->start( pImpl
->aText
, pImpl
->nMax
);
262 pImpl
->xStatusInd
->setValue( nVal
);
265 if ( pImpl
->bWaitMode
)
267 if ( pImpl
->xObjSh
.is() )
269 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst(pImpl
->xObjSh
.get() );
271 pFrame
= SfxViewFrame::GetNext( *pFrame
, pImpl
->xObjSh
.get() ) )
272 pFrame
->GetWindow().EnterWait();
276 if ( pImpl
->xObjSh
.is() )
278 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst(pImpl
->xObjSh
.get());
280 pFrame
->GetBindings().ENTERREGISTRATIONS();
287 void SfxProgress::Suspend()
291 Interrupts the status of the display
295 <SfxProgress::Resume()>
299 if( pImpl
->pActiveProgress
) return;
303 SAL_INFO("sfx.bastyp", "SfxProgress: suspended");
306 if ( pImpl
->xStatusInd
.is() )
308 pImpl
->xStatusInd
->reset();
311 if ( pImpl
->xObjSh
.is() )
313 for ( SfxViewFrame
*pFrame
=
314 SfxViewFrame::GetFirst(pImpl
->xObjSh
.get());
316 pFrame
= SfxViewFrame::GetNext( *pFrame
, pImpl
->xObjSh
.get() ) )
317 pFrame
->GetWindow().LeaveWait();
319 if ( pImpl
->xObjSh
.is() )
321 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pImpl
->xObjSh
.get() );
323 pFrame
->GetBindings().LEAVEREGISTRATIONS();
328 void SfxProgress::Reschedule()
332 Reschedule, callable from the outside
336 SFX_STACK(SfxProgress::Reschedule
);
340 SfxProgress
* SfxProgress::GetActiveProgress
342 SfxObjectShell
const * pDocSh
/* the <SfxObjectShell>, which should be
343 queried after a current <SfxProgress>,
344 or 0 if a current SfxProgress for the
345 entire application should be obtained.
346 The pointer only needs at the time of
347 the call to be valid.
353 This method is used to check whether and which <SfxProgress> is currently
354 active for a specific instance of SfxObjectShell or even an entire
355 application. This can for example be used to check for Time-Out-Events, etc.
357 Instead of a pointer to the SfxProgress the SfxObjectShell may be
358 pointed at the SfxProgress of the application, with the query
359 'SfxProgress:: GetActiveProgress (pMyDocSh)' thus the current
360 SfxProgress of 'pMyDocSh' is delivered, otherwise the SfxProgress of
361 the application or a 0-pointer.
365 If no SfxProgress is running in the application and also not at the
366 specified SfxObjectShell, then this method will always return 0,
367 even if one SfxProgress runs on another SfxObjectShell.
371 <SfxApplication::GetProgress()const>
372 <SfxObjectShell::GetProgress()const>
376 if ( !SfxApplication::Get() )
379 SfxProgress
*pProgress
= nullptr;
381 pProgress
= pDocSh
->GetProgress();
383 pProgress
= SfxGetpApp()->GetProgress();
388 void SfxProgress::EnterLock()
390 SfxGetpApp()->Get_Impl()->nRescheduleLocks
++;
394 void SfxProgress::LeaveLock()
396 SfxAppData_Impl
*pImp
= SfxGetpApp()->Get_Impl();
397 DBG_ASSERT( 0 != pImp
->nRescheduleLocks
, "SFxProgress::LeaveLock but no locks" );
398 pImp
->nRescheduleLocks
--;
401 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */