xref: /AOO41X/main/svx/source/form/formdispatchinterceptor.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
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 
DBG_NAME(DispatchInterceptionMultiplexer)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     //------------------------------------------------------------------------
~DispatchInterceptionMultiplexer()96     DispatchInterceptionMultiplexer::~DispatchInterceptionMultiplexer()
97     {
98         if (!rBHelper.bDisposed)
99             dispose();
100 
101         DBG_DTOR(DispatchInterceptionMultiplexer,NULL);
102     }
103 
104     //------------------------------------------------------------------------------
queryDispatch(const URL & aURL,const::rtl::OUString & aTargetFrameName,sal_Int32 nSearchFlags)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
queryDispatches(const Sequence<DispatchDescriptor> & aDescripts)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     //------------------------------------------------------------------------------
getSlaveDispatchProvider()136     Reference< XDispatchProvider > SAL_CALL DispatchInterceptionMultiplexer::getSlaveDispatchProvider(  ) throw(RuntimeException)
137     {
138         ::osl::MutexGuard aGuard( *m_pMutex );
139         return m_xSlaveDispatcher;
140     }
141 
142     //------------------------------------------------------------------------------
setSlaveDispatchProvider(const Reference<XDispatchProvider> & xNewDispatchProvider)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     //------------------------------------------------------------------------------
getMasterDispatchProvider(void)150     Reference< XDispatchProvider> SAL_CALL DispatchInterceptionMultiplexer::getMasterDispatchProvider(void) throw( RuntimeException )
151     {
152         ::osl::MutexGuard aGuard( *m_pMutex );
153         return m_xMasterDispatcher;
154     }
155 
156     //------------------------------------------------------------------------------
setMasterDispatchProvider(const Reference<XDispatchProvider> & xNewSupplier)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     //------------------------------------------------------------------------------
disposing(const EventObject & Source)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     //------------------------------------------------------------------------------
ImplDetach()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     //------------------------------------------------------------------------------
disposing()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