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 {
85 osl::MutexGuard aGuard( m_aMutex );
86
87 if ( ! m_pDisposeEventListeners )
88 m_pDisposeEventListeners =
89 new cppu::OInterfaceContainerHelper( m_aMutex );
90
91 m_pDisposeEventListeners->addInterface( Listener );
92 }
93
94
95 void SAL_CALL
removeEventListener(const uno::Reference<lang::XEventListener> & Listener)96 Interceptor::removeEventListener(
97 const uno::Reference< lang::XEventListener >& Listener )
98 {
99 osl::MutexGuard aGuard( m_aMutex );
100
101 if ( m_pDisposeEventListeners )
102 m_pDisposeEventListeners->removeInterface( Listener );
103 }
104
105
Interceptor(DocumentHolder * pDocHolder)106 Interceptor::Interceptor( DocumentHolder* pDocHolder )
107 : m_pDocHolder( pDocHolder ),
108 m_pDisposeEventListeners(0),
109 m_pStatCL(0)
110 {
111 m_aInterceptedURL[0] = rtl::OUString(
112 RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
113 m_aInterceptedURL[1] = rtl::OUString(
114 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll"));
115 m_aInterceptedURL[2] = rtl::OUString(
116 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
117 m_aInterceptedURL[3] = rtl::OUString(
118 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
119 m_aInterceptedURL[4] = rtl::OUString(
120 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
121 m_aInterceptedURL[5] = rtl::OUString(
122 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
123
124 }
125
126
~Interceptor()127 Interceptor::~Interceptor()
128 {
129 if( m_pDisposeEventListeners )
130 delete m_pDisposeEventListeners;
131
132 if(m_pStatCL)
133 delete m_pStatCL;
134 }
135
136
137
138 //XDispatch
139 void SAL_CALL
dispatch(const util::URL & URL,const uno::Sequence<beans::PropertyValue> & Arguments)140 Interceptor::dispatch(
141 const util::URL& URL,
142 const uno::Sequence<
143 beans::PropertyValue >& Arguments )
144 {
145 osl::MutexGuard aGuard(m_aMutex);
146 if( m_pDocHolder )
147 {
148 if(URL.Complete == m_aInterceptedURL[0])
149 m_pDocHolder->GetEmbedObject()->SaveObject_Impl();
150 else if(URL.Complete == m_aInterceptedURL[2] ||
151 URL.Complete == m_aInterceptedURL[3] ||
152 URL.Complete == m_aInterceptedURL[4])
153 {
154 try {
155 m_pDocHolder->GetEmbedObject()->changeState( embed::EmbedStates::RUNNING );
156 }
157 catch( uno::Exception& )
158 {
159 }
160 }
161 else if ( URL.Complete == m_aInterceptedURL[5] )
162 {
163 uno::Sequence< beans::PropertyValue > aNewArgs = Arguments;
164 sal_Int32 nInd = 0;
165
166 while( nInd < aNewArgs.getLength() )
167 {
168 if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) )
169 {
170 aNewArgs[nInd].Value <<= sal_True;
171 break;
172 }
173 nInd++;
174 }
175
176 if ( nInd == aNewArgs.getLength() )
177 {
178 aNewArgs.realloc( nInd + 1 );
179 aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" );
180 aNewArgs[nInd].Value <<= sal_True;
181 }
182
183 uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
184 URL, ::rtl::OUString::createFromAscii( "_self" ), 0 );
185 if ( xDispatch.is() )
186 xDispatch->dispatch( URL, aNewArgs );
187 }
188 }
189 }
190
191 void SAL_CALL
addStatusListener(const uno::Reference<frame::XStatusListener> & Control,const util::URL & URL)192 Interceptor::addStatusListener(
193 const uno::Reference<
194 frame::XStatusListener >& Control,
195 const util::URL& URL )
196 {
197 if(!Control.is())
198 return;
199
200 if(URL.Complete == m_aInterceptedURL[0])
201 { // Save
202 frame::FeatureStateEvent aStateEvent;
203 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
204 aStateEvent.FeatureDescriptor = rtl::OUString(
205 RTL_CONSTASCII_USTRINGPARAM("Update"));
206 aStateEvent.IsEnabled = sal_True;
207 aStateEvent.Requery = sal_False;
208 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($1) ")) + m_pDocHolder->GetTitle() );
209 Control->statusChanged(aStateEvent);
210
211 {
212 osl::MutexGuard aGuard(m_aMutex);
213 if(!m_pStatCL)
214 m_pStatCL =
215 new StatusChangeListenerContainer(m_aMutex);
216 }
217
218 m_pStatCL->addInterface(URL.Complete,Control);
219 return;
220 }
221
222 sal_Int32 i = 2;
223 if(URL.Complete == m_aInterceptedURL[i] ||
224 URL.Complete == m_aInterceptedURL[++i] ||
225 URL.Complete == m_aInterceptedURL[++i] )
226 { // Close and return
227 frame::FeatureStateEvent aStateEvent;
228 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
229 aStateEvent.FeatureDescriptor = rtl::OUString(
230 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
231 aStateEvent.IsEnabled = sal_True;
232 aStateEvent.Requery = sal_False;
233 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($2) ")) + m_pDocHolder->GetTitle() );
234 Control->statusChanged(aStateEvent);
235
236
237 {
238 osl::MutexGuard aGuard(m_aMutex);
239 if(!m_pStatCL)
240 m_pStatCL =
241 new StatusChangeListenerContainer(m_aMutex);
242 }
243
244 m_pStatCL->addInterface(URL.Complete,Control);
245 return;
246 }
247
248 if(URL.Complete == m_aInterceptedURL[5])
249 { // SaveAs
250 frame::FeatureStateEvent aStateEvent;
251 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
252 aStateEvent.FeatureDescriptor = rtl::OUString(
253 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
254 aStateEvent.IsEnabled = sal_True;
255 aStateEvent.Requery = sal_False;
256 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
257 Control->statusChanged(aStateEvent);
258
259 {
260 osl::MutexGuard aGuard(m_aMutex);
261 if(!m_pStatCL)
262 m_pStatCL =
263 new StatusChangeListenerContainer(m_aMutex);
264 }
265
266 m_pStatCL->addInterface(URL.Complete,Control);
267 return;
268 }
269
270 }
271
272
273 void SAL_CALL
removeStatusListener(const uno::Reference<frame::XStatusListener> & Control,const util::URL & URL)274 Interceptor::removeStatusListener(
275 const uno::Reference<
276 frame::XStatusListener >& Control,
277 const util::URL& URL )
278 {
279 if(!(Control.is() && m_pStatCL))
280 return;
281 else {
282 m_pStatCL->removeInterface(URL.Complete,Control);
283 return;
284 }
285 }
286
287
288 //XInterceptorInfo
289 uno::Sequence< ::rtl::OUString >
290 SAL_CALL
getInterceptedURLs()291 Interceptor::getInterceptedURLs( )
292 {
293 // now implemented as update
294
295 return m_aInterceptedURL;
296 }
297
298
299 // XDispatchProvider
300
301 uno::Reference< frame::XDispatch > SAL_CALL
queryDispatch(const util::URL & URL,const::rtl::OUString & TargetFrameName,sal_Int32 SearchFlags)302 Interceptor::queryDispatch(
303 const util::URL& URL,
304 const ::rtl::OUString& TargetFrameName,
305 sal_Int32 SearchFlags )
306 {
307 osl::MutexGuard aGuard(m_aMutex);
308 if(URL.Complete == m_aInterceptedURL[0])
309 return (frame::XDispatch*)this;
310 else if(URL.Complete == m_aInterceptedURL[1])
311 return (frame::XDispatch*)0 ;
312 else if(URL.Complete == m_aInterceptedURL[2])
313 return (frame::XDispatch*)this;
314 else if(URL.Complete == m_aInterceptedURL[3])
315 return (frame::XDispatch*)this;
316 else if(URL.Complete == m_aInterceptedURL[4])
317 return (frame::XDispatch*)this;
318 else if(URL.Complete == m_aInterceptedURL[5])
319 return (frame::XDispatch*)this;
320 else {
321 if(m_xSlaveDispatchProvider.is())
322 return m_xSlaveDispatchProvider->queryDispatch(
323 URL,TargetFrameName,SearchFlags);
324 else
325 return uno::Reference<frame::XDispatch>(0);
326 }
327 }
328
329 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
queryDispatches(const uno::Sequence<frame::DispatchDescriptor> & Requests)330 Interceptor::queryDispatches(
331 const uno::Sequence<frame::DispatchDescriptor >& Requests )
332 {
333 uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
334 osl::MutexGuard aGuard(m_aMutex);
335 if(m_xSlaveDispatchProvider.is())
336 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
337 else
338 aRet.realloc(Requests.getLength());
339
340 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
341 if(m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete)
342 aRet[i] = (frame::XDispatch*) this;
343 else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
344 aRet[i] = (frame::XDispatch*) 0;
345 else if(m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete)
346 aRet[i] = (frame::XDispatch*) this;
347 else if(m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete)
348 aRet[i] = (frame::XDispatch*) this;
349 else if(m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete)
350 aRet[i] = (frame::XDispatch*) this;
351 else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
352 aRet[i] = (frame::XDispatch*) this;
353
354 return aRet;
355 }
356
357
358
359 //XDispatchProviderInterceptor
360
361 uno::Reference< frame::XDispatchProvider > SAL_CALL
getSlaveDispatchProvider()362 Interceptor::getSlaveDispatchProvider( )
363 {
364 osl::MutexGuard aGuard(m_aMutex);
365 return m_xSlaveDispatchProvider;
366 }
367
368 void SAL_CALL
setSlaveDispatchProvider(const uno::Reference<frame::XDispatchProvider> & NewDispatchProvider)369 Interceptor::setSlaveDispatchProvider(
370 const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider )
371 {
372 osl::MutexGuard aGuard(m_aMutex);
373 m_xSlaveDispatchProvider = NewDispatchProvider;
374 }
375
376
377 uno::Reference< frame::XDispatchProvider > SAL_CALL
getMasterDispatchProvider()378 Interceptor::getMasterDispatchProvider( )
379 {
380 osl::MutexGuard aGuard(m_aMutex);
381 return m_xMasterDispatchProvider;
382 }
383
384
385 void SAL_CALL
setMasterDispatchProvider(const uno::Reference<frame::XDispatchProvider> & NewSupplier)386 Interceptor::setMasterDispatchProvider(
387 const uno::Reference< frame::XDispatchProvider >& NewSupplier )
388 {
389 osl::MutexGuard aGuard(m_aMutex);
390 m_xMasterDispatchProvider = NewSupplier;
391 }
392