diff options
author | Oliver Bolte <obo@openoffice.org> | 2004-07-06 11:13:27 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2004-07-06 11:13:27 +0000 |
commit | ca7c215434516002758585616e2892a881c364c3 (patch) | |
tree | 861e30054054a49d84ecd7ff2f7a928ff7828090 /svtools/source/uno | |
parent | f80f396375cee01c89df7e1c5114101ffb7996ac (diff) |
INTEGRATION: CWS docking1 (1.1.2); FILE ADDED
2004/06/05 16:32:00 cd 1.1.2.2: #i26252# Removed obsolete member
2004/05/12 08:06:22 cd 1.1.2.1: #i26252# Added new class to support frame status listener
Diffstat (limited to 'svtools/source/uno')
-rw-r--r-- | svtools/source/uno/framestatuslistener.cxx | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/svtools/source/uno/framestatuslistener.cxx b/svtools/source/uno/framestatuslistener.cxx new file mode 100644 index 000000000000..ed0a66041748 --- /dev/null +++ b/svtools/source/uno/framestatuslistener.cxx @@ -0,0 +1,491 @@ +/************************************************************************* + * + * $RCSfile: framestatuslistener.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: obo $ $Date: 2004-07-06 12:13:27 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVTOOLS_FRAMESTATUSLISTENER_HXX +#include <framestatuslistener.hxx> +#endif + +#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_ +#include <com/sun/star/frame/XDispatchProvider.hpp> +#endif + +#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ +#include <com/sun/star/lang/DisposedException.hpp> +#endif + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; + +namespace svt +{ + +FrameStatusListener::FrameStatusListener( + const Reference< XMultiServiceFactory >& rServiceManager, + const Reference< XFrame >& xFrame ) : + OWeakObject() + , m_xServiceManager( rServiceManager ) + , m_xFrame( xFrame ) + , m_bInitialized( sal_True ) + , m_bDisposed( sal_False ) +{ +} + +FrameStatusListener::~FrameStatusListener() +{ +} + +Reference< XFrame > FrameStatusListener::getFrameInterface() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xFrame; +} + +Reference< XMultiServiceFactory > FrameStatusListener::getServiceManager() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xServiceManager; +} + +// XInterface +Any SAL_CALL FrameStatusListener::queryInterface( const Type& rType ) +throw ( RuntimeException ) +{ + Any a = ::cppu::queryInterface( + rType , + static_cast< XComponent* >( this ), + static_cast< XFrameActionListener* >( this ), + static_cast< XStatusListener* >( this ), + static_cast< XEventListener* >( static_cast< XStatusListener* >( this )), + static_cast< XEventListener* >( static_cast< XFrameActionListener* >( this ))); + + if ( a.hasValue() ) + return a; + + return OWeakObject::queryInterface( rType ); +} + +void SAL_CALL FrameStatusListener::acquire() throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL FrameStatusListener::release() throw () +{ + OWeakObject::release(); +} + +// XComponent +void SAL_CALL FrameStatusListener::dispose() +throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( m_bDisposed ) + throw DisposedException(); + + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + try + { + Reference< XDispatch > xDispatch( pIter->second ); + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + + ++pIter; + } + + m_bDisposed = sal_True; +} + +void SAL_CALL FrameStatusListener::addEventListener( const Reference< XEventListener >& ) +throw ( RuntimeException ) +{ + // helper class for status updates - no need to support listener +} + +void SAL_CALL FrameStatusListener::removeEventListener( const Reference< XEventListener >& ) +throw ( RuntimeException ) +{ + // helper class for status updates - no need to support listener +} + +// XEventListener +void SAL_CALL FrameStatusListener::disposing( const EventObject& Source ) +throw ( RuntimeException ) +{ + Reference< XInterface > xSource( Source.Source ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + // Compare references and release dispatch references if they are equal. + Reference< XInterface > xIfac( pIter->second, UNO_QUERY ); + if ( xSource == xIfac ) + pIter->second.clear(); + } + + Reference< XInterface > xIfac( m_xFrame, UNO_QUERY ); + if ( xIfac == xSource ) + m_xFrame.clear(); +} + +// XStatusListener +void SAL_CALL FrameStatusListener::statusChanged( const FeatureStateEvent& Event ) +throw ( RuntimeException ) +{ + // must be implemented by sub class +} + +void FrameStatusListener::frameAction( const FrameActionEvent& Action ) +throw ( RuntimeException ) +{ + if ( Action.Action == FrameAction_CONTEXT_CHANGED ) + bindListener(); +} + +void FrameStatusListener::addStatusListener( const rtl::OUString& aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + + // Already in the list of status listener. Do nothing. + if ( pIter != m_aListenerMap.end() ) + return; + + // Check if we are already initialized. Implementation starts adding itself as status listener when + // intialize is called. + if ( !m_bInitialized ) + { + // Put into the hash_map of status listener. Will be activated when initialized is called + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() )); + return; + } + else + { + // Add status listener directly as intialize has already been called. + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xOldDispatch( pIter->second ); + pIter->second = xDispatch; + + try + { + if ( xOldDispatch.is() ) + xOldDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + else + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch )); + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + try + { + if ( xDispatch.is() ) + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } +} + +void FrameStatusListener::removeStatusListener( const rtl::OUString& aCommandURL ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xDispatch( pIter->second ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + m_aListenerMap.erase( pIter ); + + try + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +void FrameStatusListener::bindListener() +{ + std::vector< Listener > aDispatchVector; + Reference< XStatusListener > xStatusListener; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + + // Query for dispatch object. Old dispatch will be released with this, too. + try + { + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + } + catch ( Exception& ) + { + } + pIter->second = xDispatch; + + Listener aListener( aTargetURL, xDispatch ); + aDispatchVector.push_back( aListener ); + ++pIter; + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + if ( xStatusListener.is() ) + { + try + { + for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ ) + { + Listener& rListener = aDispatchVector[i]; + if ( rListener.xDispatch.is() ) + rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL ); + } + } + catch ( Exception& ) + { + } + } +} + +void FrameStatusListener::unbindListener() +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + pIter->second.clear(); + ++pIter; + } + } +} + +void FrameStatusListener::updateStatus( const rtl::OUString aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Try to find a dispatch object for the requested command URL + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 ); + } + } + + if ( xDispatch.is() && xStatusListener.is() ) + { + // Catch exception as we release our mutex, it is possible that someone else + // has already disposed this instance! + // Add/remove status listener to get a update status information from the + // requested command. + try + { + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +} // svt |