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