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] = ".uno:Save";
131 m_aInterceptedURL
[1] = ".uno:SaveAll";
132 m_aInterceptedURL
[2] = ".uno:CloseDoc";
133 m_aInterceptedURL
[3] = ".uno:CloseWin";
134 m_aInterceptedURL
[4] = ".uno:CloseFrame";
135 m_aInterceptedURL
[5] = ".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
= "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
= "Update";
264 aStateEvent
.State
<<= (OUString("($1) ") + aTitle
);
269 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
270 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
271 aStateEvent
.State
<<= (OUString("($3)"));
275 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
276 aStateEvent
.FeatureDescriptor
= "Close and Return";
277 aStateEvent
.State
<<= (OUString("($2) ") + aTitle
);
281 for(sal_Int32 k
= 0; k
< aSeq
.getLength(); ++k
)
283 uno::Reference
<frame::XStatusListener
>
284 Control(aSeq
[k
],uno::UNO_QUERY
);
286 Control
->statusChanged(aStateEvent
);
295 Interceptor::addStatusListener(
296 const uno::Reference
<
297 frame::XStatusListener
>& Control
,
298 const util::URL
& URL
)
300 uno::RuntimeException
306 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
308 DocumentHolder
* pTmpDocH
= NULL
;
309 uno::Reference
< uno::XInterface
> xLock
;
311 osl::MutexGuard
aGuard(m_aMutex
);
312 xLock
= m_xDocHLocker
.get();
319 aTitle
= pTmpDocH
->getTitle();
321 frame::FeatureStateEvent aStateEvent
;
322 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
323 aStateEvent
.FeatureDescriptor
= "Update";
324 aStateEvent
.IsEnabled
= sal_True
;
325 aStateEvent
.Requery
= sal_False
;
326 aStateEvent
.State
<<= (OUString("($1) ") + aTitle
);
327 Control
->statusChanged(aStateEvent
);
330 osl::MutexGuard
aGuard(m_aMutex
);
333 new StatusChangeListenerContainer(m_aMutex
);
336 m_pStatCL
->addInterface(URL
.Complete
,Control
);
342 && ( URL
.Complete
== m_aInterceptedURL
[i
] ||
343 URL
.Complete
== m_aInterceptedURL
[++i
] ||
344 URL
.Complete
== m_aInterceptedURL
[++i
] ) )
345 { // Close and return
346 DocumentHolder
* pTmpDocH
= NULL
;
347 uno::Reference
< uno::XInterface
> xLock
;
349 osl::MutexGuard
aGuard(m_aMutex
);
350 xLock
= m_xDocHLocker
.get();
357 aTitle
= pTmpDocH
->getTitle();
359 frame::FeatureStateEvent aStateEvent
;
360 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
361 aStateEvent
.FeatureDescriptor
= "Close and Return";
362 aStateEvent
.IsEnabled
= sal_True
;
363 aStateEvent
.Requery
= sal_False
;
364 aStateEvent
.State
<<= (OUString("($2) ") + aTitle
);
365 Control
->statusChanged(aStateEvent
);
369 osl::MutexGuard
aGuard(m_aMutex
);
372 new StatusChangeListenerContainer(m_aMutex
);
375 m_pStatCL
->addInterface(URL
.Complete
,Control
);
379 if(URL
.Complete
== m_aInterceptedURL
[5])
381 frame::FeatureStateEvent aStateEvent
;
382 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
383 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
384 aStateEvent
.IsEnabled
= sal_True
;
385 aStateEvent
.Requery
= sal_False
;
386 aStateEvent
.State
<<= (OUString("($3)"));
387 Control
->statusChanged(aStateEvent
);
390 osl::MutexGuard
aGuard(m_aMutex
);
393 new StatusChangeListenerContainer(m_aMutex
);
396 m_pStatCL
->addInterface(URL
.Complete
,Control
);
404 Interceptor::removeStatusListener(
405 const uno::Reference
<
406 frame::XStatusListener
>& Control
,
407 const util::URL
& URL
)
409 uno::RuntimeException
412 if(!(Control
.is() && m_pStatCL
))
415 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
422 uno::Sequence
< OUString
>
424 Interceptor::getInterceptedURLs( )
426 uno::RuntimeException
429 // now implemented as update
432 uno::Sequence
< OUString
> aResult( 2 );
433 aResult
[0] = m_aInterceptedURL
[1];
434 aResult
[1] = m_aInterceptedURL
[5];
439 return m_aInterceptedURL
;
445 uno::Reference
< frame::XDispatch
> SAL_CALL
446 Interceptor::queryDispatch(
447 const util::URL
& URL
,
448 const OUString
& TargetFrameName
,
449 sal_Int32 SearchFlags
)
451 uno::RuntimeException
454 osl::MutexGuard
aGuard(m_aMutex
);
455 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
456 return (frame::XDispatch
*)this;
457 else if(URL
.Complete
== m_aInterceptedURL
[1])
458 return (frame::XDispatch
*)0 ;
459 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[2] )
460 return (frame::XDispatch
*)this;
461 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[3] )
462 return (frame::XDispatch
*)this;
463 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[4] )
464 return (frame::XDispatch
*)this;
465 else if(URL
.Complete
== m_aInterceptedURL
[5])
466 return (frame::XDispatch
*)this;
468 if(m_xSlaveDispatchProvider
.is())
469 return m_xSlaveDispatchProvider
->queryDispatch(
470 URL
,TargetFrameName
,SearchFlags
);
472 return uno::Reference
<frame::XDispatch
>(0);
476 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SAL_CALL
477 Interceptor::queryDispatches(
478 const uno::Sequence
<frame::DispatchDescriptor
>& Requests
)
480 uno::RuntimeException
483 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aRet
;
484 osl::MutexGuard
aGuard(m_aMutex
);
485 if(m_xSlaveDispatchProvider
.is())
486 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
488 aRet
.realloc(Requests
.getLength());
490 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
491 if ( !m_bLink
&& m_aInterceptedURL
[0] == Requests
[i
].FeatureURL
.Complete
)
492 aRet
[i
] = (frame::XDispatch
*) this;
493 else if(m_aInterceptedURL
[1] == Requests
[i
].FeatureURL
.Complete
)
494 aRet
[i
] = (frame::XDispatch
*) 0;
495 else if( !m_bLink
&& m_aInterceptedURL
[2] == Requests
[i
].FeatureURL
.Complete
)
496 aRet
[i
] = (frame::XDispatch
*) this;
497 else if( !m_bLink
&& m_aInterceptedURL
[3] == Requests
[i
].FeatureURL
.Complete
)
498 aRet
[i
] = (frame::XDispatch
*) this;
499 else if( !m_bLink
&& m_aInterceptedURL
[4] == Requests
[i
].FeatureURL
.Complete
)
500 aRet
[i
] = (frame::XDispatch
*) this;
501 else if(m_aInterceptedURL
[5] == Requests
[i
].FeatureURL
.Complete
)
502 aRet
[i
] = (frame::XDispatch
*) this;
509 //XDispatchProviderInterceptor
511 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
512 Interceptor::getSlaveDispatchProvider( )
514 uno::RuntimeException
517 osl::MutexGuard
aGuard(m_aMutex
);
518 return m_xSlaveDispatchProvider
;
522 Interceptor::setSlaveDispatchProvider(
523 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
525 uno::RuntimeException
528 osl::MutexGuard
aGuard(m_aMutex
);
529 m_xSlaveDispatchProvider
= NewDispatchProvider
;
533 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
534 Interceptor::getMasterDispatchProvider( )
536 uno::RuntimeException
539 osl::MutexGuard
aGuard(m_aMutex
);
540 return m_xMasterDispatchProvider
;
545 Interceptor::setMasterDispatchProvider(
546 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
548 uno::RuntimeException
551 osl::MutexGuard
aGuard(m_aMutex
);
552 m_xMasterDispatchProvider
= NewSupplier
;
555 // Fix strange warnings about some
556 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
557 // warning C4505: 'xxx' : unreferenced local function has been removed
558 #if defined(_MSC_VER)
559 #pragma warning(disable: 4505)
562 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */