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