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