1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <cppuhelper/weak.hxx>
21 #include <embeddoc.hxx>
22 #include <docholder.hxx>
23 #include <intercept.hxx>
25 using namespace ::com::sun::star
;
33 uno::Sequence
< OUString
> Interceptor::m_aInterceptedURL(IUL
);
41 const OUString
& rKey1
,
42 const OUString
& rKey2
) const
44 return !!( rKey1
== rKey2
);
51 size_t operator()( const OUString
& rName
) const
53 return rName
.hashCode();
59 class StatusChangeListenerContainer
60 : public ::cppu::OMultiTypeInterfaceContainerHelperVar
<
61 OUString
,hashOUString
,equalOUString
>
64 StatusChangeListenerContainer( ::osl::Mutex
& aMutex
)
65 : cppu::OMultiTypeInterfaceContainerHelperVar
<
66 OUString
,hashOUString
,equalOUString
>(aMutex
)
73 Interceptor::addEventListener(
74 const uno::Reference
<lang::XEventListener
>& Listener
)
75 throw( uno::RuntimeException
)
77 osl::MutexGuard
aGuard( m_aMutex
);
79 if ( ! m_pDisposeEventListeners
)
80 m_pDisposeEventListeners
=
81 new cppu::OInterfaceContainerHelper( m_aMutex
);
83 m_pDisposeEventListeners
->addInterface( Listener
);
88 Interceptor::removeEventListener(
89 const uno::Reference
< lang::XEventListener
>& Listener
)
90 throw( uno::RuntimeException
)
92 osl::MutexGuard
aGuard( m_aMutex
);
94 if ( m_pDisposeEventListeners
)
95 m_pDisposeEventListeners
->removeInterface( Listener
);
99 void SAL_CALL
Interceptor::dispose()
100 throw(::com::sun::star::uno::RuntimeException
)
102 lang::EventObject aEvt
;
103 aEvt
.Source
= static_cast< frame::XDispatch
* >( this );
105 osl::MutexGuard
aGuard(m_aMutex
);
107 if ( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
108 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
111 m_pStatCL
->disposeAndClear( aEvt
);
113 m_xSlaveDispatchProvider
= 0;
114 m_xMasterDispatchProvider
= 0;
119 Interceptor::Interceptor(
120 const ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
>& xOleAccess
,
121 DocumentHolder
* pDocH
,
123 : m_xOleAccess( xOleAccess
),
124 m_xDocHLocker( static_cast< ::cppu::OWeakObject
* >( pDocH
) ),
127 m_pDisposeEventListeners(0),
130 m_aInterceptedURL
[0] = OUString(".uno:Save");
131 m_aInterceptedURL
[1] = OUString(".uno:SaveAll");
132 m_aInterceptedURL
[2] = OUString(".uno:CloseDoc");
133 m_aInterceptedURL
[3] = OUString(".uno:CloseWin");
134 m_aInterceptedURL
[4] = OUString(".uno:CloseFrame");
135 m_aInterceptedURL
[5] = OUString(".uno:SaveAs");
139 Interceptor::~Interceptor()
141 if( m_pDisposeEventListeners
)
142 delete m_pDisposeEventListeners
;
147 DocumentHolder
* pTmpDocH
= NULL
;
148 uno::Reference
< uno::XInterface
> xLock
;
150 osl::MutexGuard
aGuard(m_aMutex
);
151 xLock
= m_xDocHLocker
.get();
157 pTmpDocH
->ClearInterceptor();
160 void Interceptor::DisconnectDocHolder()
162 osl::MutexGuard
aGuard(m_aMutex
);
163 m_xDocHLocker
.clear();
170 Interceptor::dispatch(
171 const util::URL
& URL
,
173 beans::PropertyValue
>& Arguments
)
174 throw (uno::RuntimeException
)
176 ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
> xOleAccess
;
178 osl::MutexGuard
aGuard(m_aMutex
);
179 xOleAccess
= m_xOleAccess
;
182 if ( xOleAccess
.is() )
184 LockedEmbedDocument_Impl aDocLock
= xOleAccess
->GetEmbedDocument();
185 if ( aDocLock
.GetEmbedDocument() )
187 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0])
188 aDocLock
.GetEmbedDocument()->SaveObject();
190 && ( URL
.Complete
== m_aInterceptedURL
[2] ||
191 URL
.Complete
== m_aInterceptedURL
[3] ||
192 URL
.Complete
== m_aInterceptedURL
[4] ) )
193 aDocLock
.GetEmbedDocument()->Close( 0 );
194 else if ( URL
.Complete
== m_aInterceptedURL
[5] )
196 uno::Sequence
< beans::PropertyValue
> aNewArgs
= Arguments
;
199 while( nInd
< aNewArgs
.getLength() )
201 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
203 aNewArgs
[nInd
].Value
<<= sal_True
;
209 if ( nInd
== aNewArgs
.getLength() )
211 aNewArgs
.realloc( nInd
+ 1 );
212 aNewArgs
[nInd
].Name
= OUString( "SaveTo" );
213 aNewArgs
[nInd
].Value
<<= sal_True
;
216 uno::Reference
< frame::XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
217 URL
, OUString( "_self" ), 0 );
218 if ( xDispatch
.is() )
219 xDispatch
->dispatch( URL
, aNewArgs
);
226 void Interceptor::generateFeatureStateEvent()
230 DocumentHolder
* pTmpDocH
= NULL
;
231 uno::Reference
< uno::XInterface
> xLock
;
233 osl::MutexGuard
aGuard(m_aMutex
);
234 xLock
= m_xDocHLocker
.get();
241 aTitle
= pTmpDocH
->getTitle();
243 for(int i
= 0; i
< IUL
; ++i
)
245 if( i
== 1 || m_bLink
&& i
!= 5 )
248 cppu::OInterfaceContainerHelper
* pICH
=
249 m_pStatCL
->getContainer(m_aInterceptedURL
[i
]);
250 uno::Sequence
<uno::Reference
<uno::XInterface
> > aSeq
;
252 aSeq
= pICH
->getElements();
253 if(!aSeq
.getLength())
256 frame::FeatureStateEvent aStateEvent
;
257 aStateEvent
.IsEnabled
= sal_True
;
258 aStateEvent
.Requery
= sal_False
;
262 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
263 aStateEvent
.FeatureDescriptor
= OUString("Update");
264 aStateEvent
.State
<<= (OUString(
265 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
271 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
272 aStateEvent
.FeatureDescriptor
= OUString("SaveCopyTo");
273 aStateEvent
.State
<<= (OUString(
274 RTL_CONSTASCII_USTRINGPARAM("($3)")));
278 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
279 aStateEvent
.FeatureDescriptor
= OUString("Close and Return");
280 aStateEvent
.State
<<= (OUString(
281 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
286 for(sal_Int32 k
= 0; k
< aSeq
.getLength(); ++k
)
288 uno::Reference
<frame::XStatusListener
>
289 Control(aSeq
[k
],uno::UNO_QUERY
);
291 Control
->statusChanged(aStateEvent
);
300 Interceptor::addStatusListener(
301 const uno::Reference
<
302 frame::XStatusListener
>& Control
,
303 const util::URL
& URL
)
305 uno::RuntimeException
311 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
313 DocumentHolder
* pTmpDocH
= NULL
;
314 uno::Reference
< uno::XInterface
> xLock
;
316 osl::MutexGuard
aGuard(m_aMutex
);
317 xLock
= m_xDocHLocker
.get();
324 aTitle
= pTmpDocH
->getTitle();
326 frame::FeatureStateEvent aStateEvent
;
327 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
328 aStateEvent
.FeatureDescriptor
= OUString("Update");
329 aStateEvent
.IsEnabled
= sal_True
;
330 aStateEvent
.Requery
= sal_False
;
331 aStateEvent
.State
<<= (OUString(
332 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
334 Control
->statusChanged(aStateEvent
);
337 osl::MutexGuard
aGuard(m_aMutex
);
340 new StatusChangeListenerContainer(m_aMutex
);
343 m_pStatCL
->addInterface(URL
.Complete
,Control
);
349 && ( URL
.Complete
== m_aInterceptedURL
[i
] ||
350 URL
.Complete
== m_aInterceptedURL
[++i
] ||
351 URL
.Complete
== m_aInterceptedURL
[++i
] ) )
352 { // Close and return
353 DocumentHolder
* pTmpDocH
= NULL
;
354 uno::Reference
< uno::XInterface
> xLock
;
356 osl::MutexGuard
aGuard(m_aMutex
);
357 xLock
= m_xDocHLocker
.get();
364 aTitle
= pTmpDocH
->getTitle();
366 frame::FeatureStateEvent aStateEvent
;
367 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
368 aStateEvent
.FeatureDescriptor
= OUString("Close and Return");
369 aStateEvent
.IsEnabled
= sal_True
;
370 aStateEvent
.Requery
= sal_False
;
371 aStateEvent
.State
<<= (OUString(
372 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
374 Control
->statusChanged(aStateEvent
);
378 osl::MutexGuard
aGuard(m_aMutex
);
381 new StatusChangeListenerContainer(m_aMutex
);
384 m_pStatCL
->addInterface(URL
.Complete
,Control
);
388 if(URL
.Complete
== m_aInterceptedURL
[5])
390 frame::FeatureStateEvent aStateEvent
;
391 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
392 aStateEvent
.FeatureDescriptor
= OUString("SaveCopyTo");
393 aStateEvent
.IsEnabled
= sal_True
;
394 aStateEvent
.Requery
= sal_False
;
395 aStateEvent
.State
<<= (OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
396 Control
->statusChanged(aStateEvent
);
399 osl::MutexGuard
aGuard(m_aMutex
);
402 new StatusChangeListenerContainer(m_aMutex
);
405 m_pStatCL
->addInterface(URL
.Complete
,Control
);
413 Interceptor::removeStatusListener(
414 const uno::Reference
<
415 frame::XStatusListener
>& Control
,
416 const util::URL
& URL
)
418 uno::RuntimeException
421 if(!(Control
.is() && m_pStatCL
))
424 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
431 uno::Sequence
< OUString
>
433 Interceptor::getInterceptedURLs( )
435 uno::RuntimeException
438 // now implemented as update
441 uno::Sequence
< OUString
> aResult( 2 );
442 aResult
[0] = m_aInterceptedURL
[1];
443 aResult
[1] = m_aInterceptedURL
[5];
448 return m_aInterceptedURL
;
454 uno::Reference
< frame::XDispatch
> SAL_CALL
455 Interceptor::queryDispatch(
456 const util::URL
& URL
,
457 const OUString
& TargetFrameName
,
458 sal_Int32 SearchFlags
)
460 uno::RuntimeException
463 osl::MutexGuard
aGuard(m_aMutex
);
464 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
465 return (frame::XDispatch
*)this;
466 else if(URL
.Complete
== m_aInterceptedURL
[1])
467 return (frame::XDispatch
*)0 ;
468 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[2] )
469 return (frame::XDispatch
*)this;
470 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[3] )
471 return (frame::XDispatch
*)this;
472 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[4] )
473 return (frame::XDispatch
*)this;
474 else if(URL
.Complete
== m_aInterceptedURL
[5])
475 return (frame::XDispatch
*)this;
477 if(m_xSlaveDispatchProvider
.is())
478 return m_xSlaveDispatchProvider
->queryDispatch(
479 URL
,TargetFrameName
,SearchFlags
);
481 return uno::Reference
<frame::XDispatch
>(0);
485 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SAL_CALL
486 Interceptor::queryDispatches(
487 const uno::Sequence
<frame::DispatchDescriptor
>& Requests
)
489 uno::RuntimeException
492 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aRet
;
493 osl::MutexGuard
aGuard(m_aMutex
);
494 if(m_xSlaveDispatchProvider
.is())
495 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
497 aRet
.realloc(Requests
.getLength());
499 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
500 if ( !m_bLink
&& m_aInterceptedURL
[0] == Requests
[i
].FeatureURL
.Complete
)
501 aRet
[i
] = (frame::XDispatch
*) this;
502 else if(m_aInterceptedURL
[1] == Requests
[i
].FeatureURL
.Complete
)
503 aRet
[i
] = (frame::XDispatch
*) 0;
504 else if( !m_bLink
&& m_aInterceptedURL
[2] == Requests
[i
].FeatureURL
.Complete
)
505 aRet
[i
] = (frame::XDispatch
*) this;
506 else if( !m_bLink
&& m_aInterceptedURL
[3] == Requests
[i
].FeatureURL
.Complete
)
507 aRet
[i
] = (frame::XDispatch
*) this;
508 else if( !m_bLink
&& m_aInterceptedURL
[4] == Requests
[i
].FeatureURL
.Complete
)
509 aRet
[i
] = (frame::XDispatch
*) this;
510 else if(m_aInterceptedURL
[5] == Requests
[i
].FeatureURL
.Complete
)
511 aRet
[i
] = (frame::XDispatch
*) this;
518 //XDispatchProviderInterceptor
520 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
521 Interceptor::getSlaveDispatchProvider( )
523 uno::RuntimeException
526 osl::MutexGuard
aGuard(m_aMutex
);
527 return m_xSlaveDispatchProvider
;
531 Interceptor::setSlaveDispatchProvider(
532 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
534 uno::RuntimeException
537 osl::MutexGuard
aGuard(m_aMutex
);
538 m_xSlaveDispatchProvider
= NewDispatchProvider
;
542 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
543 Interceptor::getMasterDispatchProvider( )
545 uno::RuntimeException
548 osl::MutexGuard
aGuard(m_aMutex
);
549 return m_xMasterDispatchProvider
;
554 Interceptor::setMasterDispatchProvider(
555 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
557 uno::RuntimeException
560 osl::MutexGuard
aGuard(m_aMutex
);
561 m_xMasterDispatchProvider
= NewSupplier
;
564 // Fix strange warnings about some
565 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
566 // warning C4505: 'xxx' : unreferenced local function has been removed
567 #if defined(_MSC_VER)
568 #pragma warning(disable: 4505)
571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */