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