| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include "formfeaturedispatcher.hxx" |
| |
| #include <comphelper/namedvaluecollection.hxx> |
| #include <tools/diagnose_ex.h> |
| |
| //........................................................................ |
| namespace svx |
| { |
| //........................................................................ |
| |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::form::runtime; |
| |
| //==================================================================== |
| //= OSingleFeatureDispatcher |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| OSingleFeatureDispatcher::OSingleFeatureDispatcher( const URL& _rFeatureURL, const sal_Int16 _nFormFeature, |
| const Reference< XFormOperations >& _rxFormOperations, ::osl::Mutex& _rMutex ) |
| :m_rMutex( _rMutex ) |
| ,m_aStatusListeners( _rMutex ) |
| ,m_xFormOperations( _rxFormOperations ) |
| ,m_aFeatureURL( _rFeatureURL ) |
| ,m_nFormFeature( _nFormFeature ) |
| ,m_bLastKnownEnabled( sal_False ) |
| ,m_bDisposed( sal_False ) |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| void OSingleFeatureDispatcher::dispose() |
| { |
| { |
| ::osl::MutexGuard aGuard( m_rMutex ); |
| if ( m_bDisposed ) |
| return; |
| } |
| |
| EventObject aDisposeEvent( *this ); |
| m_aStatusListeners.disposeAndClear( aDisposeEvent ); |
| |
| { |
| ::osl::MutexGuard aGuard( m_rMutex ); |
| m_bDisposed = sal_True; |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void OSingleFeatureDispatcher::getUnoState( FeatureStateEvent& /* [out] */ _rState ) const |
| { |
| _rState.Source = *const_cast< OSingleFeatureDispatcher* >( this ); |
| |
| FeatureState aState( m_xFormOperations->getState( m_nFormFeature ) ); |
| |
| _rState.FeatureURL = m_aFeatureURL; |
| _rState.IsEnabled = aState.Enabled; |
| _rState.Requery = sal_False; |
| _rState.State = aState.State; |
| } |
| |
| //-------------------------------------------------------------------- |
| void OSingleFeatureDispatcher::updateAllListeners() |
| { |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); |
| |
| FeatureStateEvent aUnoState; |
| getUnoState( aUnoState ); |
| |
| if ( ( m_aLastKnownState == aUnoState.State ) && ( m_bLastKnownEnabled == aUnoState.IsEnabled ) ) |
| return; |
| |
| m_aLastKnownState = aUnoState.State; |
| m_bLastKnownEnabled = aUnoState.IsEnabled; |
| |
| notifyStatus( NULL, aGuard ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void OSingleFeatureDispatcher::notifyStatus( const Reference< XStatusListener >& _rxListener, ::osl::ClearableMutexGuard& _rFreeForNotification ) |
| { |
| FeatureStateEvent aUnoState; |
| getUnoState( aUnoState ); |
| |
| if ( _rxListener.is() ) |
| { |
| try |
| { |
| _rFreeForNotification.clear(); |
| _rxListener->statusChanged( aUnoState ); |
| } |
| catch( const Exception& ) |
| { |
| OSL_ENSURE( sal_False, "OSingleFeatureDispatcher::notifyStatus: caught an exception!" ); |
| } |
| } |
| else |
| { |
| ::cppu::OInterfaceIteratorHelper aIter( m_aStatusListeners ); |
| _rFreeForNotification.clear(); |
| |
| while ( aIter.hasMoreElements() ) |
| { |
| try |
| { |
| static_cast< XStatusListener* >( aIter.next() )->statusChanged( aUnoState ); |
| } |
| catch( const DisposedException& ) |
| { |
| OSL_ENSURE( sal_False, "OSingleFeatureDispatcher::notifyStatus: caught a DisposedException - removing the listener!" ); |
| aIter.remove( ); |
| } |
| catch( const Exception& ) |
| { |
| OSL_ENSURE( sal_False, "OSingleFeatureDispatcher::notifyStatus: caught a generic exception while notifying a single listener!" ); |
| } |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL OSingleFeatureDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException) |
| { |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); |
| checkAlive(); |
| |
| OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::dispatch: not responsible for this URL!" ); |
| (void)_rURL; |
| |
| if ( !m_xFormOperations->isEnabled( m_nFormFeature ) ) |
| return; |
| |
| // release our mutex before executing the command |
| sal_Int16 nFormFeature( m_nFormFeature ); |
| Reference< XFormOperations > xFormOperations( m_xFormOperations ); |
| aGuard.clear(); |
| |
| try |
| { |
| if ( !_rArguments.getLength() ) |
| { |
| xFormOperations->execute( nFormFeature ); |
| } |
| else |
| { // at the moment we only support one parameter |
| ::comphelper::NamedValueCollection aArgs( _rArguments ); |
| xFormOperations->executeWithArguments( nFormFeature, aArgs.getNamedValues() ); |
| } |
| } |
| catch( const RuntimeException& ) |
| { |
| throw; |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL OSingleFeatureDispatcher::addStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL ) throw (RuntimeException) |
| { |
| (void)_rURL; |
| OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::addStatusListener: unexpected URL!" ); |
| OSL_ENSURE( _rxControl.is(), "OSingleFeatureDispatcher::addStatusListener: senseless call!" ); |
| if ( !_rxControl.is() ) |
| return; |
| |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); |
| if ( m_bDisposed ) |
| { |
| EventObject aDisposeEvent( *this ); |
| aGuard.clear(); |
| _rxControl->disposing( aDisposeEvent ); |
| return; |
| } |
| |
| m_aStatusListeners.addInterface( _rxControl ); |
| |
| // initially update the status |
| notifyStatus( _rxControl, aGuard ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL OSingleFeatureDispatcher::removeStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL ) throw (RuntimeException) |
| { |
| (void)_rURL; |
| OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::removeStatusListener: unexpected URL!" ); |
| OSL_ENSURE( _rxControl.is(), "OSingleFeatureDispatcher::removeStatusListener: senseless call!" ); |
| if ( !_rxControl.is() ) |
| return; |
| |
| ::osl::MutexGuard aGuard( m_rMutex ); |
| checkAlive(); |
| |
| m_aStatusListeners.removeInterface( _rxControl ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void OSingleFeatureDispatcher::checkAlive() const SAL_THROW((DisposedException)) |
| { |
| if ( m_bDisposed ) |
| throw DisposedException( ::rtl::OUString(), *const_cast< OSingleFeatureDispatcher* >( this ) ); |
| } |
| |
| //........................................................................ |
| } // namespace svx |
| //........................................................................ |