summaryrefslogtreecommitdiffstats
path: root/sfx2/source/bastyp/progress.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/bastyp/progress.cxx')
-rw-r--r--sfx2/source/bastyp/progress.cxx401
1 files changed, 401 insertions, 0 deletions
diff --git a/sfx2/source/bastyp/progress.cxx b/sfx2/source/bastyp/progress.cxx
new file mode 100644
index 000000000..6d73d8316
--- /dev/null
+++ b/sfx2/source/bastyp/progress.cxx
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <sfx2/progress.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+
+#include <svl/eitem.hxx>
+#include <tools/debug.hxx>
+#include <sal/log.hxx>
+
+#include <appdata.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include <sfxtypes.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <workwin.hxx>
+#include <sfxbasecontroller_internal.hxx>
+#include <time.h>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::task;
+
+struct SfxProgress_Impl
+{
+ Reference < XStatusIndicator > xStatusInd;
+ OUString aText;
+ sal_uInt32 nMax;
+ clock_t nCreate;
+ bool bWaitMode;
+ bool bRunning;
+
+ SfxProgress* pActiveProgress;
+ SfxObjectShellRef xObjSh;
+ SfxWorkWindow* pWorkWin;
+ SfxViewFrame* pView;
+
+ explicit SfxProgress_Impl();
+};
+
+SfxProgress_Impl::SfxProgress_Impl()
+ : nMax(0)
+ , nCreate(0)
+ , bWaitMode(false)
+ , bRunning(false)
+ , pActiveProgress(nullptr)
+ , pWorkWin(nullptr)
+ , pView(nullptr)
+{
+}
+
+
+SfxProgress::SfxProgress
+(
+ SfxObjectShell* pObjSh, /* The action is performed on the
+ SfxObjectShell which can be NULL.
+ When it is then the application will be
+ used */
+
+ const OUString& rText, /* Text, which appears before the Statusmonitor
+ in the status line */
+
+ sal_uInt32 nRange, /* Max value for range */
+
+ bool bWait /* Activate the wait-Pointer initially (TRUE) */
+)
+
+/* [Description]
+
+ The constructor of the class SfxProgress switches the SfxObjectShell
+ passed as parameter and SfxViewFrames which display this document in
+ a progress mode. Ie as long as one of those SfxViewFrame instances is
+ active the associated SfxDispatcher and associated Window is disabled.
+ A progress-bar will be displayed in the status bar,
+*/
+
+: pImpl( new SfxProgress_Impl ),
+ nVal(0),
+ bSuspended(true)
+{
+ pImpl->bRunning = true;
+
+ pImpl->xObjSh = pObjSh;
+ pImpl->aText = rText;
+ pImpl->nMax = nRange;
+ pImpl->bWaitMode = bWait;
+ pImpl->nCreate = Get10ThSec();
+ SAL_INFO(
+ "sfx.bastyp",
+ "SfxProgress: created for '" << rText << "' at " << pImpl->nCreate
+ << "ds");
+ pImpl->pWorkWin = nullptr;
+ pImpl->pView = nullptr;
+
+ pImpl->pActiveProgress = GetActiveProgress( pObjSh );
+ if ( pObjSh )
+ pObjSh->SetProgress_Impl(this);
+ else if( !pImpl->pActiveProgress )
+ SfxGetpApp()->SetProgress_Impl(this);
+ Resume();
+}
+
+
+SfxProgress::~SfxProgress()
+
+/* [Description]
+
+ The destructor of the class SfxProgress restores the old status,
+ the documents are released again and the status bar shows the items again.
+*/
+
+{
+ Stop();
+ if ( pImpl->xStatusInd.is() )
+ pImpl->xStatusInd->end();
+}
+
+
+void SfxProgress::Stop()
+
+/* [Description]
+
+ Early Exit of <SfxProgress>.
+*/
+
+{
+ if( pImpl->pActiveProgress )
+ {
+ if ( pImpl->xObjSh.is() && pImpl->xObjSh->GetProgress() == this )
+ pImpl->xObjSh->SetProgress_Impl(nullptr);
+ return;
+ }
+
+ if ( !pImpl->bRunning )
+ return;
+ pImpl->bRunning = false;
+ SAL_INFO(
+ "sfx.bastyp", "SfxProgress: destroyed at " << Get10ThSec() << "ds");
+
+ Suspend();
+ if ( pImpl->xObjSh.is() )
+ pImpl->xObjSh->SetProgress_Impl(nullptr);
+ else
+ SfxGetpApp()->SetProgress_Impl(nullptr);
+}
+
+void SfxProgress::SetState
+(
+ sal_uInt32 nNewVal, /* new value for the progress bar */
+
+ sal_uInt32 nNewRange /* new maximum value, 0 for retaining the old */
+)
+/* [Description]
+
+ Setting the current status, after a time delay Reschedule is called.
+*/
+
+{
+ if( pImpl->pActiveProgress ) return;
+
+ nVal = nNewVal;
+
+ // new Range?
+ if ( nNewRange && nNewRange != pImpl->nMax )
+ {
+ SAL_INFO(
+ "sfx.bastyp",
+ "SfxProgress: range changed from " << pImpl->nMax << " to "
+ << nNewRange);
+ pImpl->nMax = nNewRange;
+ }
+
+ if ( !pImpl->xStatusInd.is() )
+ {
+ // get the active ViewFrame of the document this progress is working on
+ // if it doesn't work on a document, take the current ViewFrame
+ SfxObjectShell* pObjSh = pImpl->xObjSh.get();
+ pImpl->pView = SfxViewFrame::Current();
+ DBG_ASSERT( pImpl->pView || pObjSh, "Can't make progress bar!");
+ if ( pObjSh && ( !pImpl->pView || pObjSh != pImpl->pView->GetObjectShell() ) )
+ {
+ // current document does not belong to current ViewFrame; take it's first visible ViewFrame
+ SfxViewFrame* pDocView = SfxViewFrame::GetFirst( pObjSh );
+ if ( pDocView )
+ pImpl->pView = pDocView;
+ else
+ {
+ // don't show status indicator for hidden documents (only valid while loading)
+ SfxMedium* pMedium = pObjSh->GetMedium();
+ const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_HIDDEN, false);
+ if ( !pHiddenItem || !pHiddenItem->GetValue() )
+ {
+ const SfxUnoAnyItem* pIndicatorItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pMedium->GetItemSet(), SID_PROGRESS_STATUSBAR_CONTROL, false);
+ Reference< XStatusIndicator > xInd;
+ if ( pIndicatorItem && (pIndicatorItem->GetValue()>>=xInd) )
+ pImpl->xStatusInd = xInd;
+ }
+ }
+ }
+ else if ( pImpl->pView )
+ {
+ pImpl->pWorkWin = SfxGetpApp()->GetWorkWindow_Impl( pImpl->pView );
+ if ( pImpl->pWorkWin )
+ pImpl->xStatusInd = pImpl->pWorkWin->GetStatusIndicator();
+ }
+
+ if ( pImpl->xStatusInd.is() )
+ {
+ pImpl->xStatusInd->start( pImpl->aText, pImpl->nMax );
+ pImpl->pView = nullptr;
+ }
+ }
+
+ if ( pImpl->xStatusInd.is() )
+ {
+ pImpl->xStatusInd->setValue( nNewVal );
+ }
+}
+
+
+void SfxProgress::Resume()
+
+/* [Description]
+
+ Resumed the status of the display after an interrupt.
+
+ [Cross-reference]
+
+ <SfxProgress::Suspend()>
+*/
+
+{
+ if( pImpl->pActiveProgress ) return;
+ if ( !bSuspended )
+ return;
+
+ SAL_INFO("sfx.bastyp", "SfxProgress: resumed");
+ if ( pImpl->xStatusInd.is() )
+ {
+ pImpl->xStatusInd->start( pImpl->aText, pImpl->nMax );
+ pImpl->xStatusInd->setValue( nVal );
+ }
+
+ if ( pImpl->bWaitMode )
+ {
+ if ( pImpl->xObjSh.is() )
+ {
+ for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImpl->xObjSh.get() );
+ pFrame;
+ pFrame = SfxViewFrame::GetNext( *pFrame, pImpl->xObjSh.get() ) )
+ pFrame->GetWindow().EnterWait();
+ }
+ }
+
+ if ( pImpl->xObjSh.is() )
+ {
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pImpl->xObjSh.get());
+ if ( pFrame )
+ pFrame->GetBindings().ENTERREGISTRATIONS();
+ }
+
+ bSuspended = false;
+}
+
+
+void SfxProgress::Suspend()
+
+/* [Description]
+
+ Interrupts the status of the display
+
+ [Cross-reference]
+
+ <SfxProgress::Resume()>
+*/
+
+{
+ if( pImpl->pActiveProgress ) return;
+ if ( bSuspended )
+ return;
+
+ SAL_INFO("sfx.bastyp", "SfxProgress: suspended");
+ bSuspended = true;
+
+ if ( pImpl->xStatusInd.is() )
+ {
+ pImpl->xStatusInd->reset();
+ }
+
+ if ( pImpl->xObjSh.is() )
+ {
+ for ( SfxViewFrame *pFrame =
+ SfxViewFrame::GetFirst(pImpl->xObjSh.get());
+ pFrame;
+ pFrame = SfxViewFrame::GetNext( *pFrame, pImpl->xObjSh.get() ) )
+ pFrame->GetWindow().LeaveWait();
+ }
+ if ( pImpl->xObjSh.is() )
+ {
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pImpl->xObjSh.get() );
+ if ( pFrame )
+ pFrame->GetBindings().LEAVEREGISTRATIONS();
+ }
+}
+
+
+void SfxProgress::Reschedule()
+
+/* [Description]
+
+ Reschedule, callable from the outside
+*/
+
+{
+ SFX_STACK(SfxProgress::Reschedule);
+}
+
+
+SfxProgress* SfxProgress::GetActiveProgress
+(
+ SfxObjectShell const * pDocSh /* the <SfxObjectShell>, which should be
+ queried after a current <SfxProgress>,
+ or 0 if a current SfxProgress for the
+ entire application should be obtained.
+ The pointer only needs at the time of
+ the call to be valid.
+ */
+)
+
+/* [Description]
+
+ This method is used to check whether and which <SfxProgress> is currently
+ active for a specific instance of SfxObjectShell or even an entire
+ application. This can for example be used to check for Time-Out-Events, etc.
+
+ Instead of a pointer to the SfxProgress the SfxObjectShell may be
+ pointed at the SfxProgress of the application, with the query
+ 'SfxProgress:: GetActiveProgress (pMyDocSh)' thus the current
+ SfxProgress of 'pMyDocSh' is delivered, otherwise the SfxProgress of
+ the application or a 0-pointer.
+
+ [Note]
+
+ If no SfxProgress is running in the application and also not at the
+ specified SfxObjectShell, then this method will always return 0,
+ even if one SfxProgress runs on another SfxObjectShell.
+
+ [Cross-reference]
+
+ <SfxApplication::GetProgress()const>
+ <SfxObjectShell::GetProgress()const>
+*/
+
+{
+ if ( !SfxApplication::Get() )
+ return nullptr;
+
+ SfxProgress *pProgress = nullptr;
+ if ( pDocSh )
+ pProgress = pDocSh->GetProgress();
+ if ( !pProgress )
+ pProgress = SfxGetpApp()->GetProgress();
+ return pProgress;
+}
+
+
+void SfxProgress::EnterLock()
+{
+ SfxGetpApp()->Get_Impl()->nRescheduleLocks++;
+}
+
+
+void SfxProgress::LeaveLock()
+{
+ SfxAppData_Impl *pImp = SfxGetpApp()->Get_Impl();
+ DBG_ASSERT( 0 != pImp->nRescheduleLocks, "SFxProgress::LeaveLock but no locks" );
+ pImp->nRescheduleLocks--;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */