1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew 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 
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
84cdf0e10cSrcweir 		    // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
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     //------------------------------------------------------------------------
96cdf0e10cSrcweir     DispatchInterceptionMultiplexer::~DispatchInterceptionMultiplexer()
97cdf0e10cSrcweir     {
98cdf0e10cSrcweir 	    if (!rBHelper.bDisposed)
99cdf0e10cSrcweir 		    dispose();
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	    DBG_DTOR(DispatchInterceptionMultiplexer,NULL);
102cdf0e10cSrcweir     }
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     //------------------------------------------------------------------------------
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
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     //------------------------------------------------------------------------------
136cdf0e10cSrcweir     Reference< XDispatchProvider > SAL_CALL DispatchInterceptionMultiplexer::getSlaveDispatchProvider(	) throw(RuntimeException)
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( *m_pMutex );
139cdf0e10cSrcweir 	    return m_xSlaveDispatcher;
140cdf0e10cSrcweir     }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     //------------------------------------------------------------------------------
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     //------------------------------------------------------------------------------
150cdf0e10cSrcweir     Reference< XDispatchProvider> SAL_CALL DispatchInterceptionMultiplexer::getMasterDispatchProvider(void) throw( RuntimeException )
151cdf0e10cSrcweir     {
152cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( *m_pMutex );
153cdf0e10cSrcweir 	    return m_xMasterDispatcher;
154cdf0e10cSrcweir     }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     //------------------------------------------------------------------------------
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     //------------------------------------------------------------------------------
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     //------------------------------------------------------------------------------
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     //------------------------------------------------------------------------------
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