diff options
author | Rüdiger Timm <rt@openoffice.org> | 2004-11-26 13:30:46 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2004-11-26 13:30:46 +0000 |
commit | 75fc373634258b6ad6773189b36c6bda3a1a3bce (patch) | |
tree | 28fb8d28dcf5fe26cf6c8b81141f3acfdc44dc57 /framework/source | |
parent | 907f2e866a6619f0e656048245f4acd51cfb4ddd (diff) |
INTEGRATION: CWS recovery04 (1.10.242); FILE MERGED
2004/10/20 13:08:35 as 1.10.242.5: #i27726# redesign progress implementation after resync
2004/10/19 06:24:18 hro 1.10.242.4: #i28480# Resolved merge conflicts
2004/10/15 02:49:28 hro 1.10.242.3: RESYNC: (1.10-1.11); FILE MERGED
2004/08/05 11:24:48 as 1.10.242.2: #27726# make auto recovery aynchron
2004/07/23 13:46:21 hro 1.10.242.1: #i20882# Merging from recovery03
Diffstat (limited to 'framework/source')
-rw-r--r-- | framework/source/helper/statusindicatorfactory.cxx | 694 |
1 files changed, 254 insertions, 440 deletions
diff --git a/framework/source/helper/statusindicatorfactory.cxx b/framework/source/helper/statusindicatorfactory.cxx index 4721a3b5134c..70f2b1d55508 100644 --- a/framework/source/helper/statusindicatorfactory.cxx +++ b/framework/source/helper/statusindicatorfactory.cxx @@ -2,9 +2,9 @@ * * $RCSfile: statusindicatorfactory.cxx,v $ * - * $Revision: 1.11 $ + * $Revision: 1.12 $ * - * last change: $Author: obo $ $Date: 2004-09-09 17:09:26 $ + * last change: $Author: rt $ $Date: 2004-11-26 14:30:46 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,9 +59,9 @@ * ************************************************************************/ -//_________________________________________________________________________________________________________________ -// my own includes -//_________________________________________________________________________________________________________________ +//----------------------------------------------- +// my own includes + #include <algorithm> #ifndef __FRAMEWORK_HELPER_STATUSINDICATORFACTORY_HXX_ @@ -72,21 +72,28 @@ #include <helper/statusindicator.hxx> #endif -#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_ -#include <threadhelp/resetableguard.hxx> +#ifndef __FRAMEWORK_HELPER_VCLSTATUSINDICATOR_HXX_ +#include <helper/vclstatusindicator.hxx> +#endif + +#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ +#include <threadhelp/writeguard.hxx> #endif -#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_ -#include <threadhelp/transactionguard.hxx> +#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_ +#include <threadhelp/readguard.hxx> #endif #ifndef __FRAMEWORK_SERVICES_H_ #include <services.h> #endif -//_________________________________________________________________________________________________________________ -// interface includes -//_________________________________________________________________________________________________________________ +#ifndef __FRAMEWORK_PROPERTIES_H_ +#include <properties.h> +#endif + +//----------------------------------------------- +// interface includes #ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_ #include <com/sun/star/awt/Rectangle.hpp> @@ -124,9 +131,12 @@ #include <toolkit/unohlp.hxx> #endif -//_________________________________________________________________________________________________________________ -// includes of other projects -//_________________________________________________________________________________________________________________ +//----------------------------------------------- +// includes of other projects + +#ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX_ +#include <comphelper/sequenceashashmap.hxx> +#endif #ifndef _SV_SVAPP_HXX #include <vcl/svapp.hxx> @@ -141,505 +151,320 @@ #endif #include <time.h> -//_________________________________________________________________________________________________________________ -// namespace -//_________________________________________________________________________________________________________________ -namespace framework{ - -//_________________________________________________________________________________________________________________ -// non exported const -//_________________________________________________________________________________________________________________ +//----------------------------------------------- +// namespace -//_________________________________________________________________________________________________________________ -// non exported definitions -//_________________________________________________________________________________________________________________ +namespace framework{ -//_________________________________________________________________________________________________________________ -// declarations -//_________________________________________________________________________________________________________________ +//----------------------------------------------- +// definitions #define TIMEOUT_START_RESCHEDULE 10L /* 10th s */ sal_Int32 StatusIndicatorFactory::m_nInReschedule = 0; /// static counter for rescheduling -//***************************************************************************************************************** -// XInterface -//***************************************************************************************************************** -DEFINE_XINTERFACE_1 ( StatusIndicatorFactory , - OWeakObject , - DIRECT_INTERFACE(css::task::XStatusIndicatorFactory ) - ) - -/*-************************************************************************************************************//** - @short standard ctor - @descr These initialize a new instance of this class with all needed informations for work. - We use given window reference as parent of our status indicator window. - Please don't release it before you kill us - we can live with that ... but vcl will run into - problems! He miss his parent vcl window and assert "window with living child destroyed". - - @attention Normaly we don't need any mutex or lock here. These ctor isn't breakble and couldn't be called twice! - - @seealso - - - @param "xFactory" , reference to uno servicemanager to create own needed services - @return "xParentWindow", will be the parent window of our status indicator control! - - @onerror We do nothing and this instance will not ready for real working. - Calling of interface methods will throw an UninitializedException then! - @threadsafe yes -*//*-*************************************************************************************************************/ -StatusIndicatorFactory::StatusIndicatorFactory( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory , - const css::uno::Reference< css::frame::XFrame >& xFrame , - sal_Bool bShowStatusBar) - // Init baseclasses first - : ThreadHelpBase ( &Application::GetSolarMutex() ) - , TransactionBase ( ) - , ::cppu::OWeakObject ( ) - // Init member - , m_xFactory ( xFactory ) - , m_bProgressMode ( sal_False ) - , m_xFrame ( xFrame ) +//----------------------------------------------- +DEFINE_XINTERFACE_4(StatusIndicatorFactory , + OWeakObject , + DIRECT_INTERFACE(css::lang::XTypeProvider ), + DIRECT_INTERFACE(css::lang::XServiceInfo ), + DIRECT_INTERFACE(css::lang::XInitialization ), + DIRECT_INTERFACE(css::task::XStatusIndicatorFactory)) + +DEFINE_XTYPEPROVIDER_4(StatusIndicatorFactory , + css::lang::XTypeProvider , + css::lang::XServiceInfo , + css::lang::XInitialization , + css::task::XStatusIndicatorFactory) + +DEFINE_XSERVICEINFO_MULTISERVICE(StatusIndicatorFactory , + ::cppu::OWeakObject , + SERVICENAME_STATUSINDICATORFACTORY , + IMPLEMENTATIONNAME_STATUSINDICATORFACTORY) + +DEFINE_INIT_SERVICE(StatusIndicatorFactory, + { + /*Attention + I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() + to create a new instance of this class by our own supported service factory. + see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! + */ + } + ) + +//----------------------------------------------- +StatusIndicatorFactory::StatusIndicatorFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + // Init baseclasses first + : ThreadHelpBase (&Application::GetSolarMutex() ) + , ::cppu::OWeakObject( ) + // Init member + , m_xSMGR (xSMGR ) { - try - { - // Don't forget to open instance for normal working! - m_aTransactionManager.setWorkingMode( E_WORK ); +} - if (bShowStatusBar) - impl_createStatusBar(); - } - catch( css::uno::RuntimeException& ) - { - } +//----------------------------------------------- +StatusIndicatorFactory::~StatusIndicatorFactory() +{ } -/*-************************************************************************************************************//** - @short standard destructor - @descr We do nothing here! Releasing of our used references should be implemented in disposing() method. - We check calling of this method and state of this object here only and assert wrong using of class. +//----------------------------------------------- +void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) + throw(css::uno::Exception , + css::uno::RuntimeException) +{ + ::comphelper::SequenceAsHashMap lArgs(lArguments); - @seealso method disposing() + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); - @param - - @return - + m_xFrame = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_FRAME , css::uno::Reference< css::frame::XFrame >()); + m_xPluggWindow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_WINDOW, css::uno::Reference< css::awt::XWindow >() ); - @onerror - -*//*-*************************************************************************************************************/ -StatusIndicatorFactory::~StatusIndicatorFactory() -{ + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + impl_createProgress(); } -/*-************************************************************************************************************//** - @interface com.sun.star.task.XStatusIndicatorFactory - @short create new status indicator - @descr New created indicator objects share same progress window to show her informations. Only - last created one "is visible". All other are ignored. If this most active one is gone ... - the next one from stack can show his informations. He mustn't know anything about this mechanism. - It works automaticly! If a non visible indicator object is gone before he was visible ... next one - can work ... - - @seealso member m_xActiveIndicator - @seealso member m_xSharedStatusIndicator - - @param - - @return Reference to new created indicator interface object. - - @onerror We return NULL. - @threadsafe yes -*//*-*************************************************************************************************************/ -css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator() throw( css::uno::RuntimeException ) +//----------------------------------------------- +css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator() + throw(css::uno::RuntimeException) { - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); - - // Create a new indicator, initialize and add it to our stack ... - // ... but do it only, if created indicator is valid. - // Invalid objects are ignored! Change active indicator too. Only last created one could show his information. - // Attention: These StatusIndicator childs hold a weakreference to us. They mustn't be a listener at this instance. - // If we release all our references, they will die automaticly! - StatusIndicator* pIndicator = new StatusIndicator( this ); - css::uno::Reference< css::task::XStatusIndicator > xIndicator( static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY ); + StatusIndicator* pIndicator = new StatusIndicator(this); + css::uno::Reference< css::task::XStatusIndicator > xIndicator(static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY_THROW); return xIndicator; } -/*-************************************************************************************************************//** - @interface - - @short public helper methods! - @descr Our indicator childs has one shared status indicator window only to show her informations. - These window is hold by us! So they must call us. We decide, if calling child is the most active one and if - indicator is available. If both cases are true, we let him work. Otherwhise we do nothing. - - Follow methods append new child to our internal stack by calling start(), release it from stack by calling end() - and let him work by calling setText/setValue/reset(), if he is the most active one. - - @attention a) - -Normaly we could give our child indicators the shared indicator interface directly ... but nobody - decide then, which instance ist the most active one! On the other side we couldn't implement - the XStatusIndicator interface. Then we have no informations about caller and couldn't dispatch - calls from multiple childs ... So we implement it as normal C++ public functions. Child objects - check her weak references and if this reference is valid they could call the implmentation directly. - This works for remote cases too. Because we created this childs by using "new operator". So they - must be included in our local environment too ... - - b) - Make it exclusiv! Because may be we must change some thing here ... but in every case - we must be shure, that our most active child is realy the most active one. We must synchronize us - with "createStatusIndicator()"!!! - That's why we must have an exclusiv access on this member ... Create method use a write lock too. - He SET this member ... - - @seealso class StatusIndicator - - @param "xChild", child indicator object, which whish to show his information in shared status indicator - @parem "sText" , new text for showing in dialog - @parem "nRange", progress range of these child - @parem "nValue", new progress value for showing in dialog - @return - - - @onerror - - @threadsafe yes -*//*-*************************************************************************************************************/ -void StatusIndicatorFactory::start( const css::uno::Reference< css::task::XStatusIndicator >& xChild , - const ::rtl::OUString& sText , - sal_Int32 nRange ) +//----------------------------------------------- +void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild, + const ::rtl::OUString& sText , + sal_Int32 nRange) { - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); + // create new info structure for this child or move it to the front of our stack + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + m_aStack.erase(pItem); + IndicatorInfo aInfo(xChild, sText, nRange); + m_aStack.push_back (aInfo ); - IndicatorStack::iterator pItem = ::std::find( m_aStack.begin(), m_aStack.end(), xChild ); - if( pItem != m_aStack.end() ) - { - m_aStack.erase( pItem ); - } - IndicatorInfo aInfo( xChild, sText, nRange ); - m_aStack.push_back ( aInfo ); - - m_xActiveIndicator = xChild; + m_xActiveChild = xChild; + m_nStartTime = impl_get10ThSec(); - try - { - vos::OGuard aGuard( Application::GetSolarMutex() ); + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; - // Create status indicator window to shared it for all created indictaor objects by this factory. - if(!m_xProgress.is()) - impl_createStatusBar(); + aWriteLock.unlock(); + // <- SAFE ---------------------------------- - if(!m_bProgressMode) - { - css::uno::Reference< css::awt::XWindow > xParentWindow = implts_getParentWindow(); - if ( xParentWindow.is() ) - xParentWindow->setVisible( sal_True ); + if (xProgress.is()) + xProgress->start(sText, nRange); - if ( m_xProgress.is() ) - m_xProgress->start( sText, nRange ); - m_bProgressMode = sal_True; - } - - m_nStartTime = impl_get10ThSec(); - } - catch( css::uno::RuntimeException& ) - { - } - - aLock.unlock(); impl_reschedule(); } -void StatusIndicatorFactory::impl_createStatusBar() +//----------------------------------------------- +void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild) { - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); - - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); - css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame ); // make reference hard - css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY ); + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); - if (xPropSet.is()) - { - css::uno::Any a; - css::uno::Reference< drafts::com::sun::star::frame::XLayoutManager > xLayoutManager; - a = xPropSet->getPropertyValue( DECLARE_ASCII( "LayoutManager" )); - a >>= xLayoutManager; - if ( xLayoutManager.is() ) - { - rtl::OUString aProgressBarResStr = DECLARE_ASCII( "private:resource/progressbar/progressbar" ); - xLayoutManager->createElement( aProgressBarResStr ); - xLayoutManager->showElement( aProgressBarResStr ); - - css::uno::Reference< drafts::com::sun::star::ui::XUIElement > xProgressBar = - xLayoutManager->getElement( aProgressBarResStr ); - if ( xProgressBar.is() ) - { - m_xProgress = css::uno::Reference< css::task::XStatusIndicator >( - xProgressBar->getRealInterface(), css::uno::UNO_QUERY ); - } - } - } - aLock.unlock(); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + // reset the internal info structure related to this child + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + pItem->reset(); - css::uno::Reference< css::awt::XWindow > xParentWindow = implts_getParentWindow(); - Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow ); - if ( pParentWindow ) - { - /* SOLAR SAFE { */ - ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex()); - // force repaint! - pParentWindow->Show(); - pParentWindow->Invalidate( INVALIDATE_CHILDREN ); - pParentWindow->Flush(); - aSolarLock.clear(); - /* } SOLAR SAFE */ - } -} + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; -css::uno::Reference< css::awt::XWindow > StatusIndicatorFactory::implts_getParentWindow() -{ - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); + aReadLock.unlock(); + // <- SAFE ---------------------------------- - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); + if (xChild != xActive) + return; // not the top most child => dont change UI - css::uno::Reference< css::awt::XWindow > xWindow; - css::uno::Reference< css::frame::XFrame > xFrame; + if (xProgress.is()) + xProgress->reset(); - xFrame = m_xFrame; - aLock.unlock(); + impl_reschedule(); +} - if ( xFrame.is() ) +//----------------------------------------------- +void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + // remove this child from our stack + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + m_aStack.erase(pItem); + + // activate next child ... or finish the progress if there is no further one. + m_xActiveChild.clear(); + ::rtl::OUString sText; + sal_Int32 nValue = 0; + IndicatorStack::reverse_iterator pNext = m_aStack.rbegin(); + if (pNext != m_aStack.rend()) { - try - { - xWindow = xFrame->getContainerWindow(); - } - catch ( css::uno::Exception& ) - { - } + m_xActiveChild = pNext->m_xIndicator; + sText = pNext->m_sText; + nValue = pNext->m_nValue; } - return xWindow; -} + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; -/*-************************************************************************************************************//** - @interface - - @short public helper methods! - @descr Any child indicator will die and finish his work. Delete it from stack everytime. - We mustn't know it any longer. - But if child is the most active one - we must search another one from stack. - If we found anyone - take his values into the shared dialog ... - if no other one could be found - disable shared dialog! - - @seealso class StatusIndicator - - @param "xChild", child indicator object, which whish to show his information in shared status indicator - @parem "sText" , new text for showing in dialog - @parem "nValue", new progress value for showing in dialog - @return - - - @onerror We do nothing! - @threadsafe yes -*//*-*************************************************************************************************************/ -void StatusIndicatorFactory::end( const css::uno::Reference< css::task::XStatusIndicator >& xChild ) -{ - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); + aWriteLock.unlock(); + // <- SAFE ---------------------------------- - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); + if (!xProgress.is()) + return; - IndicatorStack::iterator pItem = ::std::find( m_aStack.begin(), m_aStack.end(), xChild ); - if( pItem != m_aStack.end() ) + if (xActive.is()) { - m_aStack.erase( pItem ); + // There is at least one further child indicator. + // Actualize our progress, so it shows these values from now. + xProgress->setText (sText ); + xProgress->setValue(nValue); } - - if( xChild == m_xActiveIndicator ) + else { - try - { - IndicatorStack::reverse_iterator pInfo = m_aStack.rbegin(); - if( pInfo != m_aStack.rend() ) - { - m_xActiveIndicator = pInfo->m_xIndicator; - if ( m_xProgress.is() ) - { - m_xProgress->setValue( (USHORT)pInfo->m_nValue ); - m_xProgress->setText( pInfo->m_sText ); - } - } - else - { - if ( m_xProgress.is() ) - m_xProgress->end(); - - // Destroy shared status indicator. - // Attention: Don't do it after destroying of parent or indicator window! - // Otherwhise vcl say: "parent with living child destroyed ..." - m_xProgress.clear(); - m_xActiveIndicator = css::uno::Reference< css::task::XStatusIndicator >(); - m_bProgressMode = sal_False; - } - } - catch( css::uno::RuntimeException& ) - { - } + // Our stack is empty. No further child exists. + // Se we must "end" our progress realy + xProgress->end(); } - aLock.unlock(); impl_reschedule(); } -/*-************************************************************************************************************//** - @interface - - @short public helper methods! - @descr Any child can try to show his information at our one shared dialog control. - But only the most active one could do that realy. The other ones don't recognize, that - her values are supressed! We select it automaticly. But her values are safed for later using. - If the current active object will gone - we must use next indicator from stack and use his values! +//----------------------------------------------- +void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild, + const ::rtl::OUString& sText ) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); - @attention It doesn't matter, if child is the most active one or not. We must - actualize his text value. Because; if he will be the next active one (if current one will gone) - we must know right value for "Text" to show it on our status window!!! - Normal we mustn't check result of ::std::find. These child MUST exist in stack. Otherwise our code is wrong!!! + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + pItem->m_sText = sText; + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; - @seealso class StatusIndicator + aWriteLock.unlock(); + // SAFE -> ---------------------------------- - @param "xChild", child indicator object, which whish to show his information in shared status indicator - @parem "sText" , new text for showing in dialog - @parem "nValue", new progress value for showing in dialog - @return - + if (xChild != xActive) + return; - @onerror We do nothing! - @threadsafe yes -*//*-*************************************************************************************************************/ -void StatusIndicatorFactory::reset( const css::uno::Reference< css::task::XStatusIndicator >& xChild ) -{ - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); + if (xProgress.is()) + xProgress->setText(sText); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); + impl_reschedule(); +} - IndicatorStack::iterator pItem = ::std::find( m_aStack.begin(), m_aStack.end(), xChild ); - pItem->reset(); +//----------------------------------------------- +void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild , + sal_Int32 nValue ) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); - if( xChild == m_xActiveIndicator ) + sal_Int32 nOldValue = 0; + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) { - try - { - if ( m_xProgress.is() ) - m_xProgress->reset(); - } - catch( css::uno::RuntimeException& ) - { - } + nOldValue = pItem->m_nValue; + pItem->m_nValue = nValue; } - aLock.unlock(); - impl_reschedule(); -} - -//***************************************************************************************************************** -void StatusIndicatorFactory::setText( const css::uno::Reference< css::task::XStatusIndicator >& xChild , - const ::rtl::OUString& sText ) -{ - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; + sal_Int32 nStartTime = m_nStartTime; - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); + aWriteLock.unlock(); + // SAFE -> ---------------------------------- - IndicatorStack::iterator pItem = ::std::find( m_aStack.begin(), m_aStack.end(), xChild ); - pItem->m_sText = sText; + if (xChild != xActive) + return; - if( xChild == m_xActiveIndicator ) + if ( + (xProgress.is() ) && + (nOldValue != nValue) + ) { - try - { - if ( m_xProgress.is() ) - m_xProgress->setText( sText ); - } - catch( css::uno::RuntimeException& ) - { - } + xProgress->setValue(nValue); } - aLock.unlock(); - impl_reschedule(); + // We start rescheduling only after 1 second - this code was successfully introduced by the sfx2 + // implementation of the progress bar. + sal_Bool bReschedule = ((impl_get10ThSec()-nStartTime ) > TIMEOUT_START_RESCHEDULE); + if (bReschedule) + impl_reschedule(); } -//***************************************************************************************************************** -void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild , - sal_Int32 nValue ) +//----------------------------------------------- +void StatusIndicatorFactory::impl_createProgress() { - /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - // Register transaction and reject wrong calls. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); + ::rtl::OUString PROGRESSBAR_RES_STR = ::rtl::OUString::createFromAscii("private:resource/progressbar/progressbar"); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ResetableGuard aLock( m_aLock ); + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); - IndicatorStack::iterator pItem = ::std::find( m_aStack.begin(), m_aStack.end(), xChild ); + css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; - sal_Int32 nOldValue = pItem->m_nValue; - pItem->m_nValue = nValue; + aReadLock.lock(); + // <- SAFE ---------------------------------- - if( xChild == m_xActiveIndicator ) + css::uno::Reference< css::task::XStatusIndicator > xProgress; + + if (xWindow.is()) { - try - { - // Set new value only if its new! StatusBar implementation redraws despite the fact - // that the value isn't new!!! - if (( nOldValue != nValue ) && m_xProgress.is() ) - m_xProgress->setValue( nValue ); - } - catch( css::uno::RuntimeException& ) + // use vcl based progress implementation in plugged mode + VCLStatusIndicator* pVCLProgress = new VCLStatusIndicator(xSMGR, xWindow); + xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pVCLProgress), css::uno::UNO_QUERY); + } + else + if (xFrame.is()) + { + // use frame layouted progress implementation + css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); + if (xPropSet.is()) { + css::uno::Reference< dcss::frame::XLayoutManager > xLayoutManager; + xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; + if (xLayoutManager.is()) + { + xLayoutManager->createElement(PROGRESSBAR_RES_STR); + xLayoutManager->showElement (PROGRESSBAR_RES_STR); + + css::uno::Reference< dcss::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESSBAR_RES_STR); + if (xProgressBar.is()) + xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY); + } } } - // We start rescheduling only after 1 second - this code was successfully introduced by the sfx2 - // implementation of the progress bar. - sal_Bool bReschedule = (( impl_get10ThSec() - m_nStartTime ) > TIMEOUT_START_RESCHEDULE ); - - aLock.unlock(); - - if ( bReschedule ) - impl_reschedule(); + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_xProgress = xProgress; + aWriteLock.lock(); + // <- SAFE ---------------------------------- } -/*-************************************************************************************************************//** - @interface - - @short helper to optimize the reschedule scheme of the status indicator - @descr This is a helper implementation to call reschedule only if are not running inside - our own reschedule call. - - @param - - @return - - - @onerror - - @threadsafe yes -*//*-*************************************************************************************************************/ +//----------------------------------------------- void StatusIndicatorFactory::impl_reschedule() { - ResetableGuard aGlobalLock( LockHelper::getGlobalLock() ); - if ( m_nInReschedule == 0 ) + // SAFE -> ---------------------------------- + WriteGuard aGlobalLock(LockHelper::getGlobalLock()); + + if (m_nInReschedule == 0) { ++m_nInReschedule; aGlobalLock.unlock(); @@ -649,22 +474,11 @@ void StatusIndicatorFactory::impl_reschedule() } } -/*-************************************************************************************************************//** - @interface - - @short - @descr - - - @param - - @return - - - @onerror - - @threadsafe yes -*//*-*************************************************************************************************************/ +//----------------------------------------------- sal_uInt32 StatusIndicatorFactory::impl_get10ThSec() { sal_uInt32 n10Ticks = 10 * (sal_uInt32)clock(); return n10Ticks / CLOCKS_PER_SEC; } -} // namespace framework +} // namespace framework |