xref: /AOO41X/main/embeddedobj/source/general/intercept.cxx (revision bfd08df8d53be340829eb05b5154718deb4e1b3d)
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_embeddedobj.hxx"
26 #include <com/sun/star/embed/EmbedStates.hpp>
27 #include <cppuhelper/weak.hxx>
28 
29 #include "intercept.hxx"
30 #include "docholder.hxx"
31 #include "commonembobj.hxx"
32 
33 using namespace ::com::sun::star;
34 
35 
36 #define IUL 6
37 
38 
39 uno::Sequence< ::rtl::OUString > Interceptor::m_aInterceptedURL(IUL);
40 
41 struct equalOUString
42 {
operator ()equalOUString43     bool operator()(
44         const rtl::OUString& rKey1,
45         const rtl::OUString& rKey2 ) const
46     {
47         return !!( rKey1 == rKey2 );
48     }
49 };
50 
51 
52 struct hashOUString
53 {
operator ()hashOUString54     size_t operator()( const rtl::OUString& rName ) const
55     {
56         return rName.hashCode();
57     }
58 };
59 
60 
61 
62 class StatusChangeListenerContainer
63     : public ::cppu::OMultiTypeInterfaceContainerHelperVar<
64 rtl::OUString,hashOUString,equalOUString>
65 {
66 public:
StatusChangeListenerContainer(::osl::Mutex & aMutex)67     StatusChangeListenerContainer( ::osl::Mutex& aMutex )
68         :  cppu::OMultiTypeInterfaceContainerHelperVar<
69     rtl::OUString,hashOUString,equalOUString>(aMutex)
70     {
71     }
72 };
73 
74 
DisconnectDocHolder()75 void Interceptor::DisconnectDocHolder()
76 {
77     osl::MutexGuard aGuard( m_aMutex );
78     m_pDocHolder = NULL;
79 }
80 
81 void SAL_CALL
addEventListener(const uno::Reference<lang::XEventListener> & Listener)82 Interceptor::addEventListener(
83     const uno::Reference<lang::XEventListener >& Listener )
84     throw( uno::RuntimeException )
85 {
86     osl::MutexGuard aGuard( m_aMutex );
87 
88     if ( ! m_pDisposeEventListeners )
89         m_pDisposeEventListeners =
90             new cppu::OInterfaceContainerHelper( m_aMutex );
91 
92     m_pDisposeEventListeners->addInterface( Listener );
93 }
94 
95 
96 void SAL_CALL
removeEventListener(const uno::Reference<lang::XEventListener> & Listener)97 Interceptor::removeEventListener(
98     const uno::Reference< lang::XEventListener >& Listener )
99     throw( uno::RuntimeException )
100 {
101     osl::MutexGuard aGuard( m_aMutex );
102 
103     if ( m_pDisposeEventListeners )
104         m_pDisposeEventListeners->removeInterface( Listener );
105 }
106 
107 
Interceptor(DocumentHolder * pDocHolder)108 Interceptor::Interceptor( DocumentHolder* pDocHolder )
109     : m_pDocHolder( pDocHolder ),
110       m_pDisposeEventListeners(0),
111       m_pStatCL(0)
112 {
113     m_aInterceptedURL[0] = rtl::OUString(
114         RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
115     m_aInterceptedURL[1] = rtl::OUString(
116         RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll"));
117     m_aInterceptedURL[2] = rtl::OUString(
118         RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
119     m_aInterceptedURL[3] = rtl::OUString(
120         RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
121     m_aInterceptedURL[4] = rtl::OUString(
122         RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
123     m_aInterceptedURL[5] = rtl::OUString(
124         RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
125 
126 }
127 
128 
~Interceptor()129 Interceptor::~Interceptor()
130 {
131     if( m_pDisposeEventListeners )
132         delete m_pDisposeEventListeners;
133 
134     if(m_pStatCL)
135         delete m_pStatCL;
136 }
137 
138 
139 
140 //XDispatch
141 void SAL_CALL
dispatch(const util::URL & URL,const uno::Sequence<beans::PropertyValue> & Arguments)142 Interceptor::dispatch(
143     const util::URL& URL,
144     const uno::Sequence<
145     beans::PropertyValue >& Arguments )
146     throw (uno::RuntimeException)
147 {
148     osl::MutexGuard aGuard(m_aMutex);
149     if( m_pDocHolder )
150     {
151         if(URL.Complete == m_aInterceptedURL[0])
152             m_pDocHolder->GetEmbedObject()->SaveObject_Impl();
153         else if(URL.Complete == m_aInterceptedURL[2] ||
154                 URL.Complete == m_aInterceptedURL[3] ||
155                 URL.Complete == m_aInterceptedURL[4])
156         {
157             try {
158                 m_pDocHolder->GetEmbedObject()->changeState( embed::EmbedStates::RUNNING );
159             }
160             catch( uno::Exception& )
161             {
162             }
163         }
164         else if ( URL.Complete == m_aInterceptedURL[5] )
165         {
166             uno::Sequence< beans::PropertyValue > aNewArgs = Arguments;
167             sal_Int32 nInd = 0;
168 
169             while( nInd < aNewArgs.getLength() )
170             {
171                 if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) )
172                 {
173                     aNewArgs[nInd].Value <<= sal_True;
174                     break;
175                 }
176                 nInd++;
177             }
178 
179             if ( nInd == aNewArgs.getLength() )
180             {
181                 aNewArgs.realloc( nInd + 1 );
182                 aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" );
183                 aNewArgs[nInd].Value <<= sal_True;
184             }
185 
186             uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
187                 URL, ::rtl::OUString::createFromAscii( "_self" ), 0 );
188             if ( xDispatch.is() )
189                 xDispatch->dispatch( URL, aNewArgs );
190         }
191     }
192 }
193 
194 void SAL_CALL
addStatusListener(const uno::Reference<frame::XStatusListener> & Control,const util::URL & URL)195 Interceptor::addStatusListener(
196     const uno::Reference<
197     frame::XStatusListener >& Control,
198     const util::URL& URL )
199     throw (
200         uno::RuntimeException
201     )
202 {
203     if(!Control.is())
204         return;
205 
206     if(URL.Complete == m_aInterceptedURL[0])
207     {   // Save
208         frame::FeatureStateEvent aStateEvent;
209         aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
210         aStateEvent.FeatureDescriptor = rtl::OUString(
211             RTL_CONSTASCII_USTRINGPARAM("Update"));
212         aStateEvent.IsEnabled = sal_True;
213         aStateEvent.Requery = sal_False;
214         aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($1) ")) + m_pDocHolder->GetTitle() );
215         Control->statusChanged(aStateEvent);
216 
217         {
218             osl::MutexGuard aGuard(m_aMutex);
219             if(!m_pStatCL)
220                 m_pStatCL =
221                     new StatusChangeListenerContainer(m_aMutex);
222         }
223 
224         m_pStatCL->addInterface(URL.Complete,Control);
225         return;
226     }
227 
228     sal_Int32 i = 2;
229     if(URL.Complete == m_aInterceptedURL[i] ||
230        URL.Complete == m_aInterceptedURL[++i] ||
231        URL.Complete == m_aInterceptedURL[++i] )
232     {   // Close and return
233         frame::FeatureStateEvent aStateEvent;
234         aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
235         aStateEvent.FeatureDescriptor = rtl::OUString(
236             RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
237         aStateEvent.IsEnabled = sal_True;
238         aStateEvent.Requery = sal_False;
239         aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($2) ")) + m_pDocHolder->GetTitle() );
240         Control->statusChanged(aStateEvent);
241 
242 
243         {
244             osl::MutexGuard aGuard(m_aMutex);
245             if(!m_pStatCL)
246                 m_pStatCL =
247                     new StatusChangeListenerContainer(m_aMutex);
248         }
249 
250         m_pStatCL->addInterface(URL.Complete,Control);
251         return;
252     }
253 
254     if(URL.Complete == m_aInterceptedURL[5])
255     {   // SaveAs
256         frame::FeatureStateEvent aStateEvent;
257         aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
258         aStateEvent.FeatureDescriptor = rtl::OUString(
259             RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
260         aStateEvent.IsEnabled = sal_True;
261         aStateEvent.Requery = sal_False;
262         aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
263         Control->statusChanged(aStateEvent);
264 
265         {
266             osl::MutexGuard aGuard(m_aMutex);
267             if(!m_pStatCL)
268                 m_pStatCL =
269                     new StatusChangeListenerContainer(m_aMutex);
270         }
271 
272         m_pStatCL->addInterface(URL.Complete,Control);
273         return;
274     }
275 
276 }
277 
278 
279 void SAL_CALL
removeStatusListener(const uno::Reference<frame::XStatusListener> & Control,const util::URL & URL)280 Interceptor::removeStatusListener(
281     const uno::Reference<
282     frame::XStatusListener >& Control,
283     const util::URL& URL )
284     throw (
285         uno::RuntimeException
286     )
287 {
288     if(!(Control.is() && m_pStatCL))
289         return;
290     else {
291         m_pStatCL->removeInterface(URL.Complete,Control);
292         return;
293     }
294 }
295 
296 
297 //XInterceptorInfo
298 uno::Sequence< ::rtl::OUString >
299 SAL_CALL
getInterceptedURLs()300 Interceptor::getInterceptedURLs(  )
301     throw (
302         uno::RuntimeException
303     )
304 {
305     // now implemented as update
306 
307     return m_aInterceptedURL;
308 }
309 
310 
311 // XDispatchProvider
312 
313 uno::Reference< frame::XDispatch > SAL_CALL
queryDispatch(const util::URL & URL,const::rtl::OUString & TargetFrameName,sal_Int32 SearchFlags)314 Interceptor::queryDispatch(
315     const util::URL& URL,
316     const ::rtl::OUString& TargetFrameName,
317     sal_Int32 SearchFlags )
318     throw (
319         uno::RuntimeException
320     )
321 {
322     osl::MutexGuard aGuard(m_aMutex);
323     if(URL.Complete == m_aInterceptedURL[0])
324         return (frame::XDispatch*)this;
325     else if(URL.Complete == m_aInterceptedURL[1])
326         return (frame::XDispatch*)0   ;
327     else if(URL.Complete == m_aInterceptedURL[2])
328         return (frame::XDispatch*)this;
329     else if(URL.Complete == m_aInterceptedURL[3])
330         return (frame::XDispatch*)this;
331     else if(URL.Complete == m_aInterceptedURL[4])
332         return (frame::XDispatch*)this;
333     else if(URL.Complete == m_aInterceptedURL[5])
334         return (frame::XDispatch*)this;
335     else {
336         if(m_xSlaveDispatchProvider.is())
337             return m_xSlaveDispatchProvider->queryDispatch(
338                 URL,TargetFrameName,SearchFlags);
339         else
340             return uno::Reference<frame::XDispatch>(0);
341     }
342 }
343 
344 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
queryDispatches(const uno::Sequence<frame::DispatchDescriptor> & Requests)345 Interceptor::queryDispatches(
346     const uno::Sequence<frame::DispatchDescriptor >& Requests )
347     throw (
348         uno::RuntimeException
349     )
350 {
351     uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
352     osl::MutexGuard aGuard(m_aMutex);
353     if(m_xSlaveDispatchProvider.is())
354         aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
355     else
356         aRet.realloc(Requests.getLength());
357 
358     for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
359         if(m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete)
360             aRet[i] = (frame::XDispatch*) this;
361         else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
362             aRet[i] = (frame::XDispatch*) 0;
363         else if(m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete)
364             aRet[i] = (frame::XDispatch*) this;
365         else if(m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete)
366             aRet[i] = (frame::XDispatch*) this;
367         else if(m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete)
368             aRet[i] = (frame::XDispatch*) this;
369         else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
370             aRet[i] = (frame::XDispatch*) this;
371 
372     return aRet;
373 }
374 
375 
376 
377 //XDispatchProviderInterceptor
378 
379 uno::Reference< frame::XDispatchProvider > SAL_CALL
getSlaveDispatchProvider()380 Interceptor::getSlaveDispatchProvider(  )
381     throw (
382         uno::RuntimeException
383     )
384 {
385     osl::MutexGuard aGuard(m_aMutex);
386     return m_xSlaveDispatchProvider;
387 }
388 
389 void SAL_CALL
setSlaveDispatchProvider(const uno::Reference<frame::XDispatchProvider> & NewDispatchProvider)390 Interceptor::setSlaveDispatchProvider(
391     const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider )
392     throw (
393         uno::RuntimeException
394     )
395 {
396     osl::MutexGuard aGuard(m_aMutex);
397     m_xSlaveDispatchProvider = NewDispatchProvider;
398 }
399 
400 
401 uno::Reference< frame::XDispatchProvider > SAL_CALL
getMasterDispatchProvider()402 Interceptor::getMasterDispatchProvider(  )
403     throw (
404         uno::RuntimeException
405     )
406 {
407     osl::MutexGuard aGuard(m_aMutex);
408     return m_xMasterDispatchProvider;
409 }
410 
411 
412 void SAL_CALL
setMasterDispatchProvider(const uno::Reference<frame::XDispatchProvider> & NewSupplier)413 Interceptor::setMasterDispatchProvider(
414     const uno::Reference< frame::XDispatchProvider >& NewSupplier )
415     throw (
416         uno::RuntimeException
417     )
418 {
419     osl::MutexGuard aGuard(m_aMutex);
420     m_xMasterDispatchProvider = NewSupplier;
421 }
422 
423