1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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
;
44 uno::Sequence
< ::rtl::OUString
> Interceptor::m_aInterceptedURL(IUL
);
52 const rtl::OUString
& rKey1
,
53 const rtl::OUString
& rKey2
) const
55 return !!( rKey1
== rKey2
);
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
>
75 StatusChangeListenerContainer( ::osl::Mutex
& aMutex
)
76 : cppu::OMultiTypeInterfaceContainerHelperVar
<
77 rtl::OUString
,hashOUString
,equalOUString
>(aMutex
)
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
);
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
);
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
,
134 : m_xOleAccess( xOleAccess
),
135 m_xDocHLocker( static_cast< ::cppu::OWeakObject
* >( pDocH
) ),
138 m_pDisposeEventListeners(0),
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
;
164 DocumentHolder
* pTmpDocH
= NULL
;
165 uno::Reference
< uno::XInterface
> xLock
;
167 osl::MutexGuard
aGuard(m_aMutex
);
168 xLock
= m_xDocHLocker
.get();
174 pTmpDocH
->ClearInterceptor();
177 void Interceptor::DisconnectDocHolder()
179 osl::MutexGuard
aGuard(m_aMutex
);
180 m_xDocHLocker
= uno::Reference
< uno::XInterface
>();
187 Interceptor::dispatch(
188 const util::URL
& URL
,
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();
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
;
216 while( nInd
< aNewArgs
.getLength() )
218 if ( aNewArgs
[nInd
].Name
.equalsAscii( "SaveTo" ) )
220 aNewArgs
[nInd
].Value
<<= sal_True
;
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()
247 DocumentHolder
* pTmpDocH
= NULL
;
248 uno::Reference
< uno::XInterface
> xLock
;
250 osl::MutexGuard
aGuard(m_aMutex
);
251 xLock
= m_xDocHLocker
.get();
256 ::rtl::OUString aTitle
;
258 aTitle
= pTmpDocH
->getTitle();
260 for(int i
= 0; i
< IUL
; ++i
)
262 if( i
== 1 || m_bLink
&& i
!= 5 )
265 cppu::OInterfaceContainerHelper
* pICH
=
266 m_pStatCL
->getContainer(m_aInterceptedURL
[i
]);
267 uno::Sequence
<uno::Reference
<uno::XInterface
> > aSeq
;
269 aSeq
= pICH
->getElements();
270 if(!aSeq
.getLength())
273 frame::FeatureStateEvent aStateEvent
;
274 aStateEvent
.IsEnabled
= sal_True
;
275 aStateEvent
.Requery
= sal_False
;
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) ")) +
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)")));
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) ")) +
306 for(sal_Int32 k
= 0; k
< aSeq
.getLength(); ++k
)
308 uno::Reference
<frame::XStatusListener
>
309 Control(aSeq
[k
],uno::UNO_QUERY
);
311 Control
->statusChanged(aStateEvent
);
320 Interceptor::addStatusListener(
321 const uno::Reference
<
322 frame::XStatusListener
>& Control
,
323 const util::URL
& URL
)
325 uno::RuntimeException
331 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
333 DocumentHolder
* pTmpDocH
= NULL
;
334 uno::Reference
< uno::XInterface
> xLock
;
336 osl::MutexGuard
aGuard(m_aMutex
);
337 xLock
= m_xDocHLocker
.get();
342 ::rtl::OUString aTitle
;
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) ")) +
355 Control
->statusChanged(aStateEvent
);
358 osl::MutexGuard
aGuard(m_aMutex
);
361 new StatusChangeListenerContainer(m_aMutex
);
364 m_pStatCL
->addInterface(URL
.Complete
,Control
);
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();
383 ::rtl::OUString aTitle
;
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) ")) +
396 Control
->statusChanged(aStateEvent
);
400 osl::MutexGuard
aGuard(m_aMutex
);
403 new StatusChangeListenerContainer(m_aMutex
);
406 m_pStatCL
->addInterface(URL
.Complete
,Control
);
410 if(URL
.Complete
== m_aInterceptedURL
[5])
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
);
425 new StatusChangeListenerContainer(m_aMutex
);
428 m_pStatCL
->addInterface(URL
.Complete
,Control
);
436 Interceptor::removeStatusListener(
437 const uno::Reference
<
438 frame::XStatusListener
>& Control
,
439 const util::URL
& URL
)
441 uno::RuntimeException
444 if(!(Control
.is() && m_pStatCL
))
447 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
454 uno::Sequence
< ::rtl::OUString
>
456 Interceptor::getInterceptedURLs( )
458 uno::RuntimeException
461 // now implemented as update
464 uno::Sequence
< ::rtl::OUString
> aResult( 2 );
465 aResult
[0] = m_aInterceptedURL
[1];
466 aResult
[1] = m_aInterceptedURL
[5];
471 return m_aInterceptedURL
;
477 uno::Reference
< frame::XDispatch
> SAL_CALL
478 Interceptor::queryDispatch(
479 const util::URL
& URL
,
480 const ::rtl::OUString
& TargetFrameName
,
481 sal_Int32 SearchFlags
)
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;
500 if(m_xSlaveDispatchProvider
.is())
501 return m_xSlaveDispatchProvider
->queryDispatch(
502 URL
,TargetFrameName
,SearchFlags
);
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
)
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
);
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;
541 //XDispatchProviderInterceptor
543 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
544 Interceptor::getSlaveDispatchProvider( )
546 uno::RuntimeException
549 osl::MutexGuard
aGuard(m_aMutex
);
550 return m_xSlaveDispatchProvider
;
554 Interceptor::setSlaveDispatchProvider(
555 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
557 uno::RuntimeException
560 osl::MutexGuard
aGuard(m_aMutex
);
561 m_xSlaveDispatchProvider
= NewDispatchProvider
;
565 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
566 Interceptor::getMasterDispatchProvider( )
568 uno::RuntimeException
571 osl::MutexGuard
aGuard(m_aMutex
);
572 return m_xMasterDispatchProvider
;
577 Interceptor::setMasterDispatchProvider(
578 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
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)