merge the formfield patch from ooo-build
[ooovba.git] / embedserv / source / embed / intercept.cxx
blobe0288e4c74a5c7832f29635cb37b60d2703a365d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: intercept.cxx,v $
10 * $Revision: 1.14.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include <cppuhelper/weak.hxx>
32 #include <embeddoc.hxx>
33 #include <docholder.hxx>
34 #include <intercept.hxx>
36 using namespace ::com::sun::star;
40 #define IUL 6
44 uno::Sequence< ::rtl::OUString > Interceptor::m_aInterceptedURL(IUL);
49 struct equalOUString
51 bool operator()(
52 const rtl::OUString& rKey1,
53 const rtl::OUString& rKey2 ) const
55 return !!( rKey1 == rKey2 );
60 struct hashOUString
62 size_t operator()( const rtl::OUString& rName ) const
64 return rName.hashCode();
70 class StatusChangeListenerContainer
71 : public ::cppu::OMultiTypeInterfaceContainerHelperVar<
72 rtl::OUString,hashOUString,equalOUString>
74 public:
75 StatusChangeListenerContainer( ::osl::Mutex& aMutex )
76 : cppu::OMultiTypeInterfaceContainerHelperVar<
77 rtl::OUString,hashOUString,equalOUString>(aMutex)
83 void SAL_CALL
84 Interceptor::addEventListener(
85 const uno::Reference<lang::XEventListener >& Listener )
86 throw( uno::RuntimeException )
88 osl::MutexGuard aGuard( m_aMutex );
90 if ( ! m_pDisposeEventListeners )
91 m_pDisposeEventListeners =
92 new cppu::OInterfaceContainerHelper( m_aMutex );
94 m_pDisposeEventListeners->addInterface( Listener );
98 void SAL_CALL
99 Interceptor::removeEventListener(
100 const uno::Reference< lang::XEventListener >& Listener )
101 throw( uno::RuntimeException )
103 osl::MutexGuard aGuard( m_aMutex );
105 if ( m_pDisposeEventListeners )
106 m_pDisposeEventListeners->removeInterface( Listener );
110 void SAL_CALL Interceptor::dispose()
111 throw(::com::sun::star::uno::RuntimeException)
113 lang::EventObject aEvt;
114 aEvt.Source = static_cast< frame::XDispatch* >( this );
116 osl::MutexGuard aGuard(m_aMutex);
118 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
119 m_pDisposeEventListeners->disposeAndClear( aEvt );
121 if(m_pStatCL)
122 m_pStatCL->disposeAndClear( aEvt );
124 m_xSlaveDispatchProvider = 0;
125 m_xMasterDispatchProvider = 0;
130 Interceptor::Interceptor(
131 const ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl >& xOleAccess,
132 DocumentHolder* pDocH,
133 sal_Bool bLink )
134 : m_xOleAccess( xOleAccess ),
135 m_xDocHLocker( static_cast< ::cppu::OWeakObject* >( pDocH ) ),
136 m_pDocH(pDocH),
137 m_pStatCL(0),
138 m_pDisposeEventListeners(0),
139 m_bLink( bLink )
141 m_aInterceptedURL[0] = rtl::OUString(
142 RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
143 m_aInterceptedURL[1] = rtl::OUString(
144 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll"));
145 m_aInterceptedURL[2] = rtl::OUString(
146 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
147 m_aInterceptedURL[3] = rtl::OUString(
148 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
149 m_aInterceptedURL[4] = rtl::OUString(
150 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
151 m_aInterceptedURL[5] = rtl::OUString(
152 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
156 Interceptor::~Interceptor()
158 if( m_pDisposeEventListeners )
159 delete m_pDisposeEventListeners;
161 if(m_pStatCL)
162 delete m_pStatCL;
164 DocumentHolder* pTmpDocH = NULL;
165 uno::Reference< uno::XInterface > xLock;
167 osl::MutexGuard aGuard(m_aMutex);
168 xLock = m_xDocHLocker.get();
169 if ( xLock.is() )
170 pTmpDocH = m_pDocH;
173 if ( pTmpDocH )
174 pTmpDocH->ClearInterceptor();
177 void Interceptor::DisconnectDocHolder()
179 osl::MutexGuard aGuard(m_aMutex);
180 m_xDocHLocker = uno::Reference< uno::XInterface >();
181 m_pDocH = NULL;
182 m_xOleAccess = NULL;
185 //XDispatch
186 void SAL_CALL
187 Interceptor::dispatch(
188 const util::URL& URL,
189 const uno::Sequence<
190 beans::PropertyValue >& Arguments )
191 throw (uno::RuntimeException)
193 ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > xOleAccess;
195 osl::MutexGuard aGuard(m_aMutex);
196 xOleAccess = m_xOleAccess;
199 if ( xOleAccess.is() )
201 LockedEmbedDocument_Impl aDocLock = xOleAccess->GetEmbedDocument();
202 if ( aDocLock.GetEmbedDocument() )
204 if( !m_bLink && URL.Complete == m_aInterceptedURL[0])
205 aDocLock.GetEmbedDocument()->SaveObject();
206 else if(!m_bLink
207 && ( URL.Complete == m_aInterceptedURL[2] ||
208 URL.Complete == m_aInterceptedURL[3] ||
209 URL.Complete == m_aInterceptedURL[4] ) )
210 aDocLock.GetEmbedDocument()->Close( 0 );
211 else if ( URL.Complete == m_aInterceptedURL[5] )
213 uno::Sequence< beans::PropertyValue > aNewArgs = Arguments;
214 sal_Int32 nInd = 0;
216 while( nInd < aNewArgs.getLength() )
218 if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) )
220 aNewArgs[nInd].Value <<= sal_True;
221 break;
223 nInd++;
226 if ( nInd == aNewArgs.getLength() )
228 aNewArgs.realloc( nInd + 1 );
229 aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" );
230 aNewArgs[nInd].Value <<= sal_True;
233 uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
234 URL, ::rtl::OUString::createFromAscii( "_self" ), 0 );
235 if ( xDispatch.is() )
236 xDispatch->dispatch( URL, aNewArgs );
243 void Interceptor::generateFeatureStateEvent()
245 if( m_pStatCL )
247 DocumentHolder* pTmpDocH = NULL;
248 uno::Reference< uno::XInterface > xLock;
250 osl::MutexGuard aGuard(m_aMutex);
251 xLock = m_xDocHLocker.get();
252 if ( xLock.is() )
253 pTmpDocH = m_pDocH;
256 ::rtl::OUString aTitle;
257 if ( pTmpDocH )
258 aTitle = pTmpDocH->getTitle();
260 for(int i = 0; i < IUL; ++i)
262 if( i == 1 || m_bLink && i != 5 )
263 continue;
265 cppu::OInterfaceContainerHelper* pICH =
266 m_pStatCL->getContainer(m_aInterceptedURL[i]);
267 uno::Sequence<uno::Reference<uno::XInterface> > aSeq;
268 if(pICH)
269 aSeq = pICH->getElements();
270 if(!aSeq.getLength())
271 continue;
273 frame::FeatureStateEvent aStateEvent;
274 aStateEvent.IsEnabled = sal_True;
275 aStateEvent.Requery = sal_False;
276 if(i == 0)
279 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
280 aStateEvent.FeatureDescriptor = rtl::OUString(
281 RTL_CONSTASCII_USTRINGPARAM("Update"));
282 aStateEvent.State <<= (rtl::OUString(
283 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
284 aTitle);
287 else if ( i == 5 )
289 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
290 aStateEvent.FeatureDescriptor = rtl::OUString(
291 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
292 aStateEvent.State <<= (rtl::OUString(
293 RTL_CONSTASCII_USTRINGPARAM("($3)")));
295 else
297 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
298 aStateEvent.FeatureDescriptor = rtl::OUString(
299 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
300 aStateEvent.State <<= (rtl::OUString(
301 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
302 aTitle);
306 for(sal_Int32 k = 0; k < aSeq.getLength(); ++k)
308 uno::Reference<frame::XStatusListener>
309 Control(aSeq[k],uno::UNO_QUERY);
310 if(Control.is())
311 Control->statusChanged(aStateEvent);
319 void SAL_CALL
320 Interceptor::addStatusListener(
321 const uno::Reference<
322 frame::XStatusListener >& Control,
323 const util::URL& URL )
324 throw (
325 uno::RuntimeException
328 if(!Control.is())
329 return;
331 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
332 { // Save
333 DocumentHolder* pTmpDocH = NULL;
334 uno::Reference< uno::XInterface > xLock;
336 osl::MutexGuard aGuard(m_aMutex);
337 xLock = m_xDocHLocker.get();
338 if ( xLock.is() )
339 pTmpDocH = m_pDocH;
342 ::rtl::OUString aTitle;
343 if ( pTmpDocH )
344 aTitle = pTmpDocH->getTitle();
346 frame::FeatureStateEvent aStateEvent;
347 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
348 aStateEvent.FeatureDescriptor = rtl::OUString(
349 RTL_CONSTASCII_USTRINGPARAM("Update"));
350 aStateEvent.IsEnabled = sal_True;
351 aStateEvent.Requery = sal_False;
352 aStateEvent.State <<= (rtl::OUString(
353 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
354 aTitle );
355 Control->statusChanged(aStateEvent);
358 osl::MutexGuard aGuard(m_aMutex);
359 if(!m_pStatCL)
360 m_pStatCL =
361 new StatusChangeListenerContainer(m_aMutex);
364 m_pStatCL->addInterface(URL.Complete,Control);
365 return;
368 sal_Int32 i = 2;
369 if ( !m_bLink
370 && ( URL.Complete == m_aInterceptedURL[i] ||
371 URL.Complete == m_aInterceptedURL[++i] ||
372 URL.Complete == m_aInterceptedURL[++i] ) )
373 { // Close and return
374 DocumentHolder* pTmpDocH = NULL;
375 uno::Reference< uno::XInterface > xLock;
377 osl::MutexGuard aGuard(m_aMutex);
378 xLock = m_xDocHLocker.get();
379 if ( xLock.is() )
380 pTmpDocH = m_pDocH;
383 ::rtl::OUString aTitle;
384 if ( pTmpDocH )
385 aTitle = pTmpDocH->getTitle();
387 frame::FeatureStateEvent aStateEvent;
388 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
389 aStateEvent.FeatureDescriptor = rtl::OUString(
390 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
391 aStateEvent.IsEnabled = sal_True;
392 aStateEvent.Requery = sal_False;
393 aStateEvent.State <<= (rtl::OUString(
394 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
395 aTitle );
396 Control->statusChanged(aStateEvent);
400 osl::MutexGuard aGuard(m_aMutex);
401 if(!m_pStatCL)
402 m_pStatCL =
403 new StatusChangeListenerContainer(m_aMutex);
406 m_pStatCL->addInterface(URL.Complete,Control);
407 return;
410 if(URL.Complete == m_aInterceptedURL[5])
411 { // SaveAs
412 frame::FeatureStateEvent aStateEvent;
413 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
414 aStateEvent.FeatureDescriptor = rtl::OUString(
415 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
416 aStateEvent.IsEnabled = sal_True;
417 aStateEvent.Requery = sal_False;
418 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
419 Control->statusChanged(aStateEvent);
422 osl::MutexGuard aGuard(m_aMutex);
423 if(!m_pStatCL)
424 m_pStatCL =
425 new StatusChangeListenerContainer(m_aMutex);
428 m_pStatCL->addInterface(URL.Complete,Control);
429 return;
435 void SAL_CALL
436 Interceptor::removeStatusListener(
437 const uno::Reference<
438 frame::XStatusListener >& Control,
439 const util::URL& URL )
440 throw (
441 uno::RuntimeException
444 if(!(Control.is() && m_pStatCL))
445 return;
446 else {
447 m_pStatCL->removeInterface(URL.Complete,Control);
448 return;
453 //XInterceptorInfo
454 uno::Sequence< ::rtl::OUString >
455 SAL_CALL
456 Interceptor::getInterceptedURLs( )
457 throw (
458 uno::RuntimeException
461 // now implemented as update
462 if ( m_bLink )
464 uno::Sequence< ::rtl::OUString > aResult( 2 );
465 aResult[0] = m_aInterceptedURL[1];
466 aResult[1] = m_aInterceptedURL[5];
468 return aResult;
471 return m_aInterceptedURL;
475 // XDispatchProvider
477 uno::Reference< frame::XDispatch > SAL_CALL
478 Interceptor::queryDispatch(
479 const util::URL& URL,
480 const ::rtl::OUString& TargetFrameName,
481 sal_Int32 SearchFlags )
482 throw (
483 uno::RuntimeException
486 osl::MutexGuard aGuard(m_aMutex);
487 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
488 return (frame::XDispatch*)this;
489 else if(URL.Complete == m_aInterceptedURL[1])
490 return (frame::XDispatch*)0 ;
491 else if( !m_bLink && URL.Complete == m_aInterceptedURL[2] )
492 return (frame::XDispatch*)this;
493 else if( !m_bLink && URL.Complete == m_aInterceptedURL[3] )
494 return (frame::XDispatch*)this;
495 else if( !m_bLink && URL.Complete == m_aInterceptedURL[4] )
496 return (frame::XDispatch*)this;
497 else if(URL.Complete == m_aInterceptedURL[5])
498 return (frame::XDispatch*)this;
499 else {
500 if(m_xSlaveDispatchProvider.is())
501 return m_xSlaveDispatchProvider->queryDispatch(
502 URL,TargetFrameName,SearchFlags);
503 else
504 return uno::Reference<frame::XDispatch>(0);
508 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
509 Interceptor::queryDispatches(
510 const uno::Sequence<frame::DispatchDescriptor >& Requests )
511 throw (
512 uno::RuntimeException
515 uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
516 osl::MutexGuard aGuard(m_aMutex);
517 if(m_xSlaveDispatchProvider.is())
518 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
519 else
520 aRet.realloc(Requests.getLength());
522 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
523 if ( !m_bLink && m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete )
524 aRet[i] = (frame::XDispatch*) this;
525 else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
526 aRet[i] = (frame::XDispatch*) 0;
527 else if( !m_bLink && m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete )
528 aRet[i] = (frame::XDispatch*) this;
529 else if( !m_bLink && m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete )
530 aRet[i] = (frame::XDispatch*) this;
531 else if( !m_bLink && m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete )
532 aRet[i] = (frame::XDispatch*) this;
533 else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
534 aRet[i] = (frame::XDispatch*) this;
536 return aRet;
541 //XDispatchProviderInterceptor
543 uno::Reference< frame::XDispatchProvider > SAL_CALL
544 Interceptor::getSlaveDispatchProvider( )
545 throw (
546 uno::RuntimeException
549 osl::MutexGuard aGuard(m_aMutex);
550 return m_xSlaveDispatchProvider;
553 void SAL_CALL
554 Interceptor::setSlaveDispatchProvider(
555 const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider )
556 throw (
557 uno::RuntimeException
560 osl::MutexGuard aGuard(m_aMutex);
561 m_xSlaveDispatchProvider = NewDispatchProvider;
565 uno::Reference< frame::XDispatchProvider > SAL_CALL
566 Interceptor::getMasterDispatchProvider( )
567 throw (
568 uno::RuntimeException
571 osl::MutexGuard aGuard(m_aMutex);
572 return m_xMasterDispatchProvider;
576 void SAL_CALL
577 Interceptor::setMasterDispatchProvider(
578 const uno::Reference< frame::XDispatchProvider >& NewSupplier )
579 throw (
580 uno::RuntimeException
583 osl::MutexGuard aGuard(m_aMutex);
584 m_xMasterDispatchProvider = NewSupplier;
587 // Fix strange warnings about some
588 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
589 // warning C4505: 'xxx' : unreferenced local function has been removed
590 #if defined(_MSC_VER)
591 #pragma warning(disable: 4505)
592 #endif