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