/************************************************************** * * 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_chart2.hxx" #include "ModifyListenerHelper.hxx" #include "WeakListenerAdapter.hxx" #include "macros.hxx" #include #include using namespace ::com::sun::star; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::rtl::OUString; namespace { void lcl_fireModifyEvent( ::cppu::OBroadcastHelper & rBroadcastHelper, const Reference< uno::XWeak > & xEventSource, const lang::EventObject * pEvent ) { ::cppu::OInterfaceContainerHelper * pCntHlp = rBroadcastHelper.getContainer( ::getCppuType( reinterpret_cast< Reference< util::XModifyListener > * >(0))); if( pCntHlp ) { lang::EventObject aEventToSend; if( pEvent ) aEventToSend = *pEvent; else aEventToSend.Source.set( xEventSource ); OSL_ENSURE( aEventToSend.Source.is(), "Sending event without source" ); ::cppu::OInterfaceIteratorHelper aIt( *pCntHlp ); while( aIt.hasMoreElements()) { Reference< util::XModifyListener > xModListener( aIt.next(), uno::UNO_QUERY ); if( xModListener.is()) xModListener->modified( aEventToSend ); } } } struct lcl_weakReferenceToSame : public ::std::unary_function< ::std::pair< ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XModifyListener >, ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > >, bool > { lcl_weakReferenceToSame( const Reference< util::XModifyListener > & xModListener ) : m_xHardRef( xModListener ) {} bool operator() ( const argument_type & xElem ) { Reference< util::XModifyListener > xWeakAsHard( xElem.first ); if( xWeakAsHard.is()) return (xWeakAsHard == m_xHardRef); return false; } private: Reference< util::XModifyListener > m_xHardRef; }; } // anonymous namespace // ================================================================================ namespace chart { namespace ModifyListenerHelper { uno::Reference< util::XModifyListener > createModifyEventForwarder() { return new ModifyEventForwarder(); } ModifyEventForwarder::ModifyEventForwarder() : ::cppu::WeakComponentImplHelper2< ::com::sun::star::util::XModifyBroadcaster, ::com::sun::star::util::XModifyListener >( m_aMutex ), m_aModifyListeners( m_aMutex ) { } void ModifyEventForwarder::FireEvent( const lang::EventObject & rEvent ) { lcl_fireModifyEvent( m_aModifyListeners, Reference< uno::XWeak >(), & rEvent ); } void ModifyEventForwarder::AddListener( const Reference< util::XModifyListener >& aListener ) { try { Reference< util::XModifyListener > xListenerToAdd( aListener ); Reference< uno::XWeak > xWeak( aListener, uno::UNO_QUERY ); if( xWeak.is()) { // remember the helper class for later remove uno::WeakReference< util::XModifyListener > xWeakRef( aListener ); xListenerToAdd.set( new WeakModifyListenerAdapter( xWeakRef )); m_aListenerMap.push_back( tListenerMap::value_type( xWeakRef, xListenerToAdd )); } m_aModifyListeners.addListener( ::getCppuType( &xListenerToAdd ), xListenerToAdd ); } catch( const uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); } } void ModifyEventForwarder::RemoveListener( const Reference< util::XModifyListener >& aListener ) { try { // look up fitting helper class that has been added Reference< util::XModifyListener > xListenerToRemove( aListener ); tListenerMap::iterator aIt( ::std::find_if( m_aListenerMap.begin(), m_aListenerMap.end(), lcl_weakReferenceToSame( aListener ))); if( aIt != m_aListenerMap.end()) { xListenerToRemove.set( (*aIt).second ); // map entry is no longer needed m_aListenerMap.erase( aIt ); } m_aModifyListeners.removeListener( ::getCppuType( &aListener ), xListenerToRemove ); } catch( const uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); } } void ModifyEventForwarder::DisposeAndClear( const Reference< uno::XWeak > & xSource ) { ::cppu::OInterfaceContainerHelper * pCntHlp = m_aModifyListeners.getContainer( ::getCppuType( reinterpret_cast< Reference< util::XModifyListener > * >(0))); if( pCntHlp ) pCntHlp->disposeAndClear( lang::EventObject( xSource ) ); } // ____ XModifyBroadcaster ____ void SAL_CALL ModifyEventForwarder::addModifyListener( const Reference< util::XModifyListener >& aListener ) throw (uno::RuntimeException) { AddListener( aListener ); } void SAL_CALL ModifyEventForwarder::removeModifyListener( const Reference< util::XModifyListener >& aListener ) throw (uno::RuntimeException) { RemoveListener( aListener ); } // ____ XModifyListener ____ void SAL_CALL ModifyEventForwarder::modified( const lang::EventObject& aEvent ) throw (uno::RuntimeException) { FireEvent( aEvent ); } // ____ XEventListener (base of XModifyListener) ____ void SAL_CALL ModifyEventForwarder::disposing( const lang::EventObject& /* Source */ ) throw (uno::RuntimeException) { // nothing } // ____ WeakComponentImplHelperBase ____ void SAL_CALL ModifyEventForwarder::disposing() { // dispose was called at this DisposeAndClear( this ); } } // namespace ModifyListenerHelper } // namespace chart