sdk-examples/trunk/cpp/components/StatusbarController/WordCountStatusbarController/BaseDispatch.cxx (183 lines of code) (raw):

/************************************************************** * * 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. * *************************************************************/ #include "BaseDispatch.hxx" #include "defines.hxx" #include <com/sun/star/frame/XFrame.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <map> #include <algorithm> using namespace com::sun::star; using namespace framework::statusbar_controller_wordcount; using com::sun::star::beans::PropertyValue; using com::sun::star::frame::FeatureStateEvent; using com::sun::star::frame::XController; using com::sun::star::frame::XDispatch; using com::sun::star::frame::XFrame; using com::sun::star::frame::XStatusListener; using com::sun::star::lang::DisposedException; using com::sun::star::uno::Reference; using com::sun::star::uno::RuntimeException; using com::sun::star::uno::Sequence; using com::sun::star::uno::UNO_QUERY; using com::sun::star::uno::UNO_QUERY_THROW; using com::sun::star::uno::XComponentContext; using com::sun::star::uno::XInterface; using com::sun::star::util::URL; using rtl::OUString; namespace { template< class Map > struct lcl_DisposeAndClearAndDeleteMapElement : public ::std::unary_function< typename Map::value_type, void > { lcl_DisposeAndClearAndDeleteMapElement( const Reference< uno::XInterface > &xEventSource ) : m_aEvent( xEventSource ) { } void operator( ) ( typename Map::value_type &rElement ) { if ( rElement.second ) { rElement.second->disposeAndClear( m_aEvent ); delete rElement.second; } } private: lang::EventObject m_aEvent; }; template< class Map > void lcl_DisposeAndClearAndDeleteAllMapElements( Map &rMap, const Reference< uno::XInterface > &xEventSource ) { ::std::for_each( rMap.begin( ), rMap.end( ), lcl_DisposeAndClearAndDeleteMapElement< Map > ( xEventSource ) ); } } BaseDispatch::BaseDispatch( const Reference< XComponentContext > &xContext, const Reference<XFrame> &xFrame, const OUString &rModuleIdentifier ) : BaseDispatch_Base( m_aMutex ) , m_xContext( xContext ) , m_xFrame( xFrame ) , m_sModuleIdentifier( rModuleIdentifier ) { OSL_TRACE( "sbctlwc::BaseDispatch::BaseDispatch" ); } BaseDispatch::~BaseDispatch() { OSL_TRACE( "sbctlwc::BaseDispatch::~BaseDispatch" ); } void SAL_CALL BaseDispatch::addStatusListener( const Reference< XStatusListener > &xControl, const URL &aURL ) throw ( RuntimeException ) { OSL_TRACE( "sbctlwc::BaseDispatch::addStatusListener" ); osl::MutexGuard aGuad( m_aMutex ); tListenerMap::iterator aIt( m_aListeners.find( aURL.Complete ) ); if ( aIt == m_aListeners.end( ) ) { aIt = m_aListeners.insert( m_aListeners.begin( ), tListenerMap::value_type( aURL.Complete, new ::cppu::OInterfaceContainerHelper( m_aMutex ) ) ); } OSL_ASSERT( aIt != m_aListeners.end( ) ); aIt->second->addInterface( xControl ); FireStatusEvent( aURL, xControl ); } void SAL_CALL BaseDispatch::removeStatusListener( const Reference< XStatusListener > &xControl, const URL &aURL ) throw ( RuntimeException ) { OSL_TRACE( "sbctlwc::BaseDispatch::removeStatusListener" ); osl::MutexGuard aGuad( m_aMutex ); tListenerMap::iterator aIt( m_aListeners.find( aURL.Complete ) ); if ( aIt != m_aListeners.end( ) ) ( *aIt ).second->removeInterface( xControl ); } void SAL_CALL BaseDispatch::disposing( ) { OSL_TRACE( "sbctlwc::BaseDispatch::disposing" ); osl::MutexGuard aGuard( m_aMutex ); lcl_DisposeAndClearAndDeleteAllMapElements( m_aListeners, static_cast < cppu::OWeakObject * > ( this ) ); m_aListeners.clear( ); } void BaseDispatch::ThrowIfDisposed( ) throw ( RuntimeException ) { if ( rBHelper.bInDispose || rBHelper.bInDispose ) throw DisposedException( ); } void BaseDispatch::FireStatusEvent() { URL aURL; if ( m_xURLTransformer.is() ) { aURL.Complete = GetCommand(); m_xURLTransformer->parseStrict( aURL ); } FireStatusEvent( aURL ); } void BaseDispatch::FireStatusEvent( const URL &rURL, const Reference< XStatusListener > &xControl ) { FeatureStateEvent aEvent = GetState( rURL ); if ( xControl.is() ) xControl->statusChanged( aEvent ); else { tListenerMap::iterator aIt( m_aListeners.find( rURL.Complete ) ); if ( aIt != m_aListeners.end() ) { if ( aIt->second ) { ::cppu::OInterfaceIteratorHelper aIntfIt( *( ( *aIt ).second ) ); while ( aIntfIt.hasMoreElements() ) { Reference< XStatusListener > xListener( aIntfIt.next(), UNO_QUERY ); try { if ( xListener.is() ) xListener->statusChanged( aEvent ); } catch ( ... ) { } } } } } } void SAL_CALL BaseDispatch::dispatch( const URL &aURL, const Sequence< PropertyValue > &lArguments ) throw ( RuntimeException ) { OSL_TRACE( "sbctlwc::BaseDispatch::dispatch" ); osl::MutexGuard aGuard( m_aMutex ); ThrowIfDisposed(); ExecuteCommand( aURL, lArguments ); } void SAL_CALL BaseDispatch::modified( const ::com::sun::star::lang::EventObject &aEvent ) throw ( RuntimeException ) { OSL_TRACE( "sbctlwc::BaseDispatch::modified" ); FireStatusEvent(); } void SAL_CALL BaseDispatch::selectionChanged( const ::com::sun::star::lang::EventObject &aEvent ) throw ( ::com::sun::star::uno::RuntimeException ) { OSL_TRACE( "sbctlwc::BaseDispatch::selectionChanged" ); FireStatusEvent(); } void SAL_CALL BaseDispatch::disposing( const ::com::sun::star::lang::EventObject &aEvent ) throw ( ::com::sun::star::uno::RuntimeException ) { OSL_TRACE( "sbctlwc::BaseDispatch::disposing(aEvent)" ); }