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
< ::rtl::OUString
> Interceptor::m_aInterceptedURL(IUL
);
41 const rtl::OUString
& rKey1
,
42 const rtl::OUString
& rKey2
) const
44 return !!( rKey1
== rKey2
);
51 size_t operator()( const rtl::OUString
& rName
) const
53 return rName
.hashCode();
59 class StatusChangeListenerContainer
60 : public ::cppu::OMultiTypeInterfaceContainerHelperVar
<
61 rtl::OUString
,hashOUString
,equalOUString
>
64 StatusChangeListenerContainer( ::osl::Mutex
& aMutex
)
65 : cppu::OMultiTypeInterfaceContainerHelperVar
<
66 rtl::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] = rtl::OUString(
131 RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
132 m_aInterceptedURL
[1] = rtl::OUString(
133 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll"));
134 m_aInterceptedURL
[2] = rtl::OUString(
135 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
136 m_aInterceptedURL
[3] = rtl::OUString(
137 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
138 m_aInterceptedURL
[4] = rtl::OUString(
139 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
140 m_aInterceptedURL
[5] = rtl::OUString(
141 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
145 Interceptor::~Interceptor()
147 if( m_pDisposeEventListeners
)
148 delete m_pDisposeEventListeners
;
153 DocumentHolder
* pTmpDocH
= NULL
;
154 uno::Reference
< uno::XInterface
> xLock
;
156 osl::MutexGuard
aGuard(m_aMutex
);
157 xLock
= m_xDocHLocker
.get();
163 pTmpDocH
->ClearInterceptor();
166 void Interceptor::DisconnectDocHolder()
168 osl::MutexGuard
aGuard(m_aMutex
);
169 m_xDocHLocker
.clear();
176 Interceptor::dispatch(
177 const util::URL
& URL
,
179 beans::PropertyValue
>& Arguments
)
180 throw (uno::RuntimeException
)
182 ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
> xOleAccess
;
184 osl::MutexGuard
aGuard(m_aMutex
);
185 xOleAccess
= m_xOleAccess
;
188 if ( xOleAccess
.is() )
190 LockedEmbedDocument_Impl aDocLock
= xOleAccess
->GetEmbedDocument();
191 if ( aDocLock
.GetEmbedDocument() )
193 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0])
194 aDocLock
.GetEmbedDocument()->SaveObject();
196 && ( URL
.Complete
== m_aInterceptedURL
[2] ||
197 URL
.Complete
== m_aInterceptedURL
[3] ||
198 URL
.Complete
== m_aInterceptedURL
[4] ) )
199 aDocLock
.GetEmbedDocument()->Close( 0 );
200 else if ( URL
.Complete
== m_aInterceptedURL
[5] )
202 uno::Sequence
< beans::PropertyValue
> aNewArgs
= Arguments
;
205 while( nInd
< aNewArgs
.getLength() )
207 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
209 aNewArgs
[nInd
].Value
<<= sal_True
;
215 if ( nInd
== aNewArgs
.getLength() )
217 aNewArgs
.realloc( nInd
+ 1 );
218 aNewArgs
[nInd
].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "SaveTo" ));
219 aNewArgs
[nInd
].Value
<<= sal_True
;
222 uno::Reference
< frame::XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
223 URL
, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "_self" )), 0 );
224 if ( xDispatch
.is() )
225 xDispatch
->dispatch( URL
, aNewArgs
);
232 void Interceptor::generateFeatureStateEvent()
236 DocumentHolder
* pTmpDocH
= NULL
;
237 uno::Reference
< uno::XInterface
> xLock
;
239 osl::MutexGuard
aGuard(m_aMutex
);
240 xLock
= m_xDocHLocker
.get();
245 ::rtl::OUString aTitle
;
247 aTitle
= pTmpDocH
->getTitle();
249 for(int i
= 0; i
< IUL
; ++i
)
251 if( i
== 1 || m_bLink
&& i
!= 5 )
254 cppu::OInterfaceContainerHelper
* pICH
=
255 m_pStatCL
->getContainer(m_aInterceptedURL
[i
]);
256 uno::Sequence
<uno::Reference
<uno::XInterface
> > aSeq
;
258 aSeq
= pICH
->getElements();
259 if(!aSeq
.getLength())
262 frame::FeatureStateEvent aStateEvent
;
263 aStateEvent
.IsEnabled
= sal_True
;
264 aStateEvent
.Requery
= sal_False
;
268 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
269 aStateEvent
.FeatureDescriptor
= rtl::OUString(
270 RTL_CONSTASCII_USTRINGPARAM("Update"));
271 aStateEvent
.State
<<= (rtl::OUString(
272 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
278 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
279 aStateEvent
.FeatureDescriptor
= rtl::OUString(
280 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
281 aStateEvent
.State
<<= (rtl::OUString(
282 RTL_CONSTASCII_USTRINGPARAM("($3)")));
286 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
287 aStateEvent
.FeatureDescriptor
= rtl::OUString(
288 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
289 aStateEvent
.State
<<= (rtl::OUString(
290 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
295 for(sal_Int32 k
= 0; k
< aSeq
.getLength(); ++k
)
297 uno::Reference
<frame::XStatusListener
>
298 Control(aSeq
[k
],uno::UNO_QUERY
);
300 Control
->statusChanged(aStateEvent
);
309 Interceptor::addStatusListener(
310 const uno::Reference
<
311 frame::XStatusListener
>& Control
,
312 const util::URL
& URL
)
314 uno::RuntimeException
320 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
322 DocumentHolder
* pTmpDocH
= NULL
;
323 uno::Reference
< uno::XInterface
> xLock
;
325 osl::MutexGuard
aGuard(m_aMutex
);
326 xLock
= m_xDocHLocker
.get();
331 ::rtl::OUString aTitle
;
333 aTitle
= pTmpDocH
->getTitle();
335 frame::FeatureStateEvent aStateEvent
;
336 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
337 aStateEvent
.FeatureDescriptor
= rtl::OUString(
338 RTL_CONSTASCII_USTRINGPARAM("Update"));
339 aStateEvent
.IsEnabled
= sal_True
;
340 aStateEvent
.Requery
= sal_False
;
341 aStateEvent
.State
<<= (rtl::OUString(
342 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
344 Control
->statusChanged(aStateEvent
);
347 osl::MutexGuard
aGuard(m_aMutex
);
350 new StatusChangeListenerContainer(m_aMutex
);
353 m_pStatCL
->addInterface(URL
.Complete
,Control
);
359 && ( URL
.Complete
== m_aInterceptedURL
[i
] ||
360 URL
.Complete
== m_aInterceptedURL
[++i
] ||
361 URL
.Complete
== m_aInterceptedURL
[++i
] ) )
362 { // Close and return
363 DocumentHolder
* pTmpDocH
= NULL
;
364 uno::Reference
< uno::XInterface
> xLock
;
366 osl::MutexGuard
aGuard(m_aMutex
);
367 xLock
= m_xDocHLocker
.get();
372 ::rtl::OUString aTitle
;
374 aTitle
= pTmpDocH
->getTitle();
376 frame::FeatureStateEvent aStateEvent
;
377 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
378 aStateEvent
.FeatureDescriptor
= rtl::OUString(
379 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
380 aStateEvent
.IsEnabled
= sal_True
;
381 aStateEvent
.Requery
= sal_False
;
382 aStateEvent
.State
<<= (rtl::OUString(
383 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
385 Control
->statusChanged(aStateEvent
);
389 osl::MutexGuard
aGuard(m_aMutex
);
392 new StatusChangeListenerContainer(m_aMutex
);
395 m_pStatCL
->addInterface(URL
.Complete
,Control
);
399 if(URL
.Complete
== m_aInterceptedURL
[5])
401 frame::FeatureStateEvent aStateEvent
;
402 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
403 aStateEvent
.FeatureDescriptor
= rtl::OUString(
404 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
405 aStateEvent
.IsEnabled
= sal_True
;
406 aStateEvent
.Requery
= sal_False
;
407 aStateEvent
.State
<<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
408 Control
->statusChanged(aStateEvent
);
411 osl::MutexGuard
aGuard(m_aMutex
);
414 new StatusChangeListenerContainer(m_aMutex
);
417 m_pStatCL
->addInterface(URL
.Complete
,Control
);
425 Interceptor::removeStatusListener(
426 const uno::Reference
<
427 frame::XStatusListener
>& Control
,
428 const util::URL
& URL
)
430 uno::RuntimeException
433 if(!(Control
.is() && m_pStatCL
))
436 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
443 uno::Sequence
< ::rtl::OUString
>
445 Interceptor::getInterceptedURLs( )
447 uno::RuntimeException
450 // now implemented as update
453 uno::Sequence
< ::rtl::OUString
> aResult( 2 );
454 aResult
[0] = m_aInterceptedURL
[1];
455 aResult
[1] = m_aInterceptedURL
[5];
460 return m_aInterceptedURL
;
466 uno::Reference
< frame::XDispatch
> SAL_CALL
467 Interceptor::queryDispatch(
468 const util::URL
& URL
,
469 const ::rtl::OUString
& TargetFrameName
,
470 sal_Int32 SearchFlags
)
472 uno::RuntimeException
475 osl::MutexGuard
aGuard(m_aMutex
);
476 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
477 return (frame::XDispatch
*)this;
478 else if(URL
.Complete
== m_aInterceptedURL
[1])
479 return (frame::XDispatch
*)0 ;
480 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[2] )
481 return (frame::XDispatch
*)this;
482 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[3] )
483 return (frame::XDispatch
*)this;
484 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[4] )
485 return (frame::XDispatch
*)this;
486 else if(URL
.Complete
== m_aInterceptedURL
[5])
487 return (frame::XDispatch
*)this;
489 if(m_xSlaveDispatchProvider
.is())
490 return m_xSlaveDispatchProvider
->queryDispatch(
491 URL
,TargetFrameName
,SearchFlags
);
493 return uno::Reference
<frame::XDispatch
>(0);
497 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SAL_CALL
498 Interceptor::queryDispatches(
499 const uno::Sequence
<frame::DispatchDescriptor
>& Requests
)
501 uno::RuntimeException
504 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aRet
;
505 osl::MutexGuard
aGuard(m_aMutex
);
506 if(m_xSlaveDispatchProvider
.is())
507 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
509 aRet
.realloc(Requests
.getLength());
511 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
512 if ( !m_bLink
&& m_aInterceptedURL
[0] == Requests
[i
].FeatureURL
.Complete
)
513 aRet
[i
] = (frame::XDispatch
*) this;
514 else if(m_aInterceptedURL
[1] == Requests
[i
].FeatureURL
.Complete
)
515 aRet
[i
] = (frame::XDispatch
*) 0;
516 else if( !m_bLink
&& m_aInterceptedURL
[2] == Requests
[i
].FeatureURL
.Complete
)
517 aRet
[i
] = (frame::XDispatch
*) this;
518 else if( !m_bLink
&& m_aInterceptedURL
[3] == Requests
[i
].FeatureURL
.Complete
)
519 aRet
[i
] = (frame::XDispatch
*) this;
520 else if( !m_bLink
&& m_aInterceptedURL
[4] == Requests
[i
].FeatureURL
.Complete
)
521 aRet
[i
] = (frame::XDispatch
*) this;
522 else if(m_aInterceptedURL
[5] == Requests
[i
].FeatureURL
.Complete
)
523 aRet
[i
] = (frame::XDispatch
*) this;
530 //XDispatchProviderInterceptor
532 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
533 Interceptor::getSlaveDispatchProvider( )
535 uno::RuntimeException
538 osl::MutexGuard
aGuard(m_aMutex
);
539 return m_xSlaveDispatchProvider
;
543 Interceptor::setSlaveDispatchProvider(
544 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
546 uno::RuntimeException
549 osl::MutexGuard
aGuard(m_aMutex
);
550 m_xSlaveDispatchProvider
= NewDispatchProvider
;
554 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
555 Interceptor::getMasterDispatchProvider( )
557 uno::RuntimeException
560 osl::MutexGuard
aGuard(m_aMutex
);
561 return m_xMasterDispatchProvider
;
566 Interceptor::setMasterDispatchProvider(
567 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
569 uno::RuntimeException
572 osl::MutexGuard
aGuard(m_aMutex
);
573 m_xMasterDispatchProvider
= NewSupplier
;
576 // Fix strange warnings about some
577 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
578 // warning C4505: 'xxx' : unreferenced local function has been removed
579 #if defined(_MSC_VER)
580 #pragma warning(disable: 4505)
583 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */