xref: /trunk/main/svx/source/form/formdispatchinterceptor.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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