1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_svx.hxx" 29 30 #include "formdispatchinterceptor.hxx" 31 32 /** === begin UNO includes === **/ 33 /** === end UNO includes === **/ 34 35 #include <tools/debug.hxx> 36 37 //........................................................................ 38 namespace svxform 39 { 40 //........................................................................ 41 42 /** === begin UNO using === **/ 43 using ::com::sun::star::uno::Reference; 44 using ::com::sun::star::uno::XInterface; 45 using ::com::sun::star::uno::UNO_QUERY; 46 using ::com::sun::star::uno::UNO_QUERY_THROW; 47 using ::com::sun::star::uno::UNO_SET_THROW; 48 using ::com::sun::star::uno::Exception; 49 using ::com::sun::star::uno::RuntimeException; 50 using ::com::sun::star::uno::Any; 51 using ::com::sun::star::uno::makeAny; 52 using ::com::sun::star::uno::Sequence; 53 using ::com::sun::star::uno::Type; 54 using ::com::sun::star::frame::XDispatchProviderInterception; 55 using ::com::sun::star::frame::XDispatchProviderInterceptor; 56 using ::com::sun::star::lang::XComponent; 57 using ::com::sun::star::util::URL; 58 using ::com::sun::star::frame::XDispatch; 59 using ::com::sun::star::frame::DispatchDescriptor; 60 using ::com::sun::star::frame::XDispatchProvider; 61 using ::com::sun::star::lang::EventObject; 62 /** === end UNO using === **/ 63 64 //======================================================================== 65 //= DispatchInterceptionMultiplexer 66 //======================================================================== 67 68 DBG_NAME(DispatchInterceptionMultiplexer) 69 //------------------------------------------------------------------------ 70 DispatchInterceptionMultiplexer::DispatchInterceptionMultiplexer( 71 const Reference< XDispatchProviderInterception >& _rxToIntercept, DispatchInterceptor* _pMaster ) 72 :DispatchInterceptionMultiplexer_BASE(_pMaster && _pMaster->getInterceptorMutex() ? *_pMaster->getInterceptorMutex() : m_aFallback) 73 ,m_aFallback() 74 ,m_pMutex( _pMaster && _pMaster->getInterceptorMutex() ? _pMaster->getInterceptorMutex() : &m_aFallback ) 75 ,m_xIntercepted(_rxToIntercept) 76 ,m_bListening(sal_False) 77 ,m_pMaster(_pMaster) 78 { 79 DBG_CTOR(DispatchInterceptionMultiplexer,NULL); 80 81 ::osl::MutexGuard aGuard( *m_pMutex ); 82 ::comphelper::increment(m_refCount); 83 if (_rxToIntercept.is()) 84 { 85 _rxToIntercept->registerDispatchProviderInterceptor((XDispatchProviderInterceptor*)this); 86 // this should make us the top-level dispatch-provider for the component, via a call to our 87 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill 88 Reference< XComponent> xInterceptedComponent(_rxToIntercept, UNO_QUERY); 89 if (xInterceptedComponent.is()) 90 { 91 xInterceptedComponent->addEventListener(this); 92 m_bListening = sal_True; 93 } 94 } 95 ::comphelper::decrement(m_refCount); 96 } 97 98 //------------------------------------------------------------------------ 99 DispatchInterceptionMultiplexer::~DispatchInterceptionMultiplexer() 100 { 101 if (!rBHelper.bDisposed) 102 dispose(); 103 104 DBG_DTOR(DispatchInterceptionMultiplexer,NULL); 105 } 106 107 //------------------------------------------------------------------------------ 108 Reference< XDispatch > SAL_CALL DispatchInterceptionMultiplexer::queryDispatch( const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags ) throw(RuntimeException) 109 { 110 ::osl::MutexGuard aGuard( *m_pMutex ); 111 Reference< XDispatch> xResult; 112 // ask our 'real' interceptor 113 if (m_pMaster) 114 xResult = m_pMaster->interceptedQueryDispatch( aURL, aTargetFrameName, nSearchFlags); 115 116 // ask our slave provider 117 if (!xResult.is() && m_xSlaveDispatcher.is()) 118 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags); 119 120 return xResult; 121 } 122 123 //------------------------------------------------------------------------------ 124 Sequence< Reference< XDispatch > > SAL_CALL 125 DispatchInterceptionMultiplexer::queryDispatches( const Sequence< DispatchDescriptor >& aDescripts ) throw(RuntimeException) 126 { 127 ::osl::MutexGuard aGuard( *m_pMutex ); 128 Sequence< Reference< XDispatch> > aReturn(aDescripts.getLength()); 129 Reference< XDispatch>* pReturn = aReturn.getArray(); 130 const DispatchDescriptor* pDescripts = aDescripts.getConstArray(); 131 for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts) 132 { 133 *pReturn = queryDispatch(pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags); 134 } 135 return aReturn; 136 } 137 138 //------------------------------------------------------------------------------ 139 Reference< XDispatchProvider > SAL_CALL DispatchInterceptionMultiplexer::getSlaveDispatchProvider( ) throw(RuntimeException) 140 { 141 ::osl::MutexGuard aGuard( *m_pMutex ); 142 return m_xSlaveDispatcher; 143 } 144 145 //------------------------------------------------------------------------------ 146 void SAL_CALL DispatchInterceptionMultiplexer::setSlaveDispatchProvider(const Reference< XDispatchProvider>& xNewDispatchProvider) throw( RuntimeException ) 147 { 148 ::osl::MutexGuard aGuard( *m_pMutex ); 149 m_xSlaveDispatcher = xNewDispatchProvider; 150 } 151 152 //------------------------------------------------------------------------------ 153 Reference< XDispatchProvider> SAL_CALL DispatchInterceptionMultiplexer::getMasterDispatchProvider(void) throw( RuntimeException ) 154 { 155 ::osl::MutexGuard aGuard( *m_pMutex ); 156 return m_xMasterDispatcher; 157 } 158 159 //------------------------------------------------------------------------------ 160 void SAL_CALL DispatchInterceptionMultiplexer::setMasterDispatchProvider(const Reference< XDispatchProvider>& xNewSupplier) throw( RuntimeException ) 161 { 162 ::osl::MutexGuard aGuard( *m_pMutex ); 163 m_xMasterDispatcher = xNewSupplier; 164 } 165 166 //------------------------------------------------------------------------------ 167 void SAL_CALL DispatchInterceptionMultiplexer::disposing(const EventObject& Source) throw( RuntimeException ) 168 { 169 if (m_bListening) 170 { 171 Reference< XDispatchProviderInterception > xIntercepted(m_xIntercepted.get(), UNO_QUERY); 172 if (Source.Source == xIntercepted) 173 ImplDetach(); 174 } 175 } 176 177 //------------------------------------------------------------------------------ 178 void DispatchInterceptionMultiplexer::ImplDetach() 179 { 180 ::osl::MutexGuard aGuard( *m_pMutex ); 181 OSL_ENSURE(m_bListening, "DispatchInterceptionMultiplexer::ImplDetach: invalid call!"); 182 183 // deregister ourself from the interception component 184 Reference< XDispatchProviderInterception > xIntercepted(m_xIntercepted.get(), UNO_QUERY); 185 if (xIntercepted.is()) 186 xIntercepted->releaseDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this)); 187 188 // m_xIntercepted = Reference< XDispatchProviderInterception >(); 189 // Don't reset m_xIntercepted: It may be needed by our owner to check for which object we were 190 // responsible. As we hold the object with a weak reference only, this should be no problem. 191 // 88936 - 23.07.2001 - frank.schoenheit@sun.com 192 m_pMaster = NULL; 193 m_pMutex = &m_aFallback; 194 m_bListening = sal_False; 195 } 196 197 //------------------------------------------------------------------------------ 198 void DispatchInterceptionMultiplexer::disposing() 199 { 200 // remove ourself as event listener from the interception component 201 if (m_bListening) 202 { 203 Reference< XComponent> xInterceptedComponent(m_xIntercepted.get(), UNO_QUERY); 204 if (xInterceptedComponent.is()) 205 xInterceptedComponent->removeEventListener(static_cast<XEventListener*>(this)); 206 207 // detach from the interception component 208 ImplDetach(); 209 } 210 } 211 212 //........................................................................ 213 } // namespace svxform 214 //........................................................................ 215