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)" );
}