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>
20 #include <cppuhelper/interfacecontainer.hxx>
22 #include <embeddoc.hxx>
23 #include <docholder.hxx>
24 #include <intercept.hxx>
26 using namespace ::com::sun::star
;
32 uno::Sequence
< OUString
> Interceptor::m_aInterceptedURL(IUL
);
34 class StatusChangeListenerContainer
35 : public cppu::OMultiTypeInterfaceContainerHelperVar
<OUString
>
38 explicit StatusChangeListenerContainer(osl::Mutex
& aMutex
)
39 : cppu::OMultiTypeInterfaceContainerHelperVar
<OUString
>(aMutex
)
46 Interceptor::addEventListener(
47 const uno::Reference
<lang::XEventListener
>& Listener
)
48 throw( uno::RuntimeException
)
50 osl::MutexGuard
aGuard( m_aMutex
);
52 if ( ! m_pDisposeEventListeners
)
53 m_pDisposeEventListeners
=
54 new comphelper::OInterfaceContainerHelper2( m_aMutex
);
56 m_pDisposeEventListeners
->addInterface( Listener
);
61 Interceptor::removeEventListener(
62 const uno::Reference
< lang::XEventListener
>& Listener
)
63 throw( uno::RuntimeException
)
65 osl::MutexGuard
aGuard( m_aMutex
);
67 if ( m_pDisposeEventListeners
)
68 m_pDisposeEventListeners
->removeInterface( Listener
);
72 void SAL_CALL
Interceptor::dispose()
73 throw(css::uno::RuntimeException
)
75 lang::EventObject aEvt
;
76 aEvt
.Source
= static_cast< frame::XDispatch
* >( this );
78 osl::MutexGuard
aGuard(m_aMutex
);
80 if ( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
81 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
84 m_pStatCL
->disposeAndClear( aEvt
);
86 m_xSlaveDispatchProvider
= 0;
87 m_xMasterDispatchProvider
= 0;
91 Interceptor::Interceptor(
92 const ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
>& xOleAccess
,
93 DocumentHolder
* pDocH
,
95 : m_xOleAccess( xOleAccess
),
96 m_xDocHLocker( static_cast< ::cppu::OWeakObject
* >( pDocH
) ),
98 m_pDisposeEventListeners(0),
102 m_aInterceptedURL
[0] = ".uno:Save";
103 m_aInterceptedURL
[1] = ".uno:SaveAll";
104 m_aInterceptedURL
[2] = ".uno:CloseDoc";
105 m_aInterceptedURL
[3] = ".uno:CloseWin";
106 m_aInterceptedURL
[4] = ".uno:CloseFrame";
107 m_aInterceptedURL
[5] = ".uno:SaveAs";
111 Interceptor::~Interceptor()
113 delete m_pDisposeEventListeners
;
116 DocumentHolder
* pTmpDocH
= NULL
;
117 uno::Reference
< uno::XInterface
> xLock
;
119 osl::MutexGuard
aGuard(m_aMutex
);
120 xLock
= m_xDocHLocker
.get();
126 pTmpDocH
->ClearInterceptor();
129 void Interceptor::DisconnectDocHolder()
131 osl::MutexGuard
aGuard(m_aMutex
);
132 m_xDocHLocker
.clear();
139 Interceptor::dispatch(
140 const util::URL
& URL
,
142 beans::PropertyValue
>& Arguments
)
143 throw (uno::RuntimeException
)
145 ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
> xOleAccess
;
147 osl::MutexGuard
aGuard(m_aMutex
);
148 xOleAccess
= m_xOleAccess
;
151 if ( xOleAccess
.is() )
153 LockedEmbedDocument_Impl aDocLock
= xOleAccess
->GetEmbedDocument();
154 if ( aDocLock
.GetEmbedDocument() )
156 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0])
157 aDocLock
.GetEmbedDocument()->SaveObject();
159 && ( URL
.Complete
== m_aInterceptedURL
[2] ||
160 URL
.Complete
== m_aInterceptedURL
[3] ||
161 URL
.Complete
== m_aInterceptedURL
[4] ) )
162 aDocLock
.GetEmbedDocument()->Close( 0 );
163 else if ( URL
.Complete
== m_aInterceptedURL
[5] )
165 uno::Sequence
< beans::PropertyValue
> aNewArgs
= Arguments
;
168 while( nInd
< aNewArgs
.getLength() )
170 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
172 aNewArgs
[nInd
].Value
<<= sal_True
;
178 if ( nInd
== aNewArgs
.getLength() )
180 aNewArgs
.realloc( nInd
+ 1 );
181 aNewArgs
[nInd
].Name
= "SaveTo";
182 aNewArgs
[nInd
].Value
<<= sal_True
;
185 uno::Reference
< frame::XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
186 URL
, OUString( "_self" ), 0 );
187 if ( xDispatch
.is() )
188 xDispatch
->dispatch( URL
, aNewArgs
);
195 void Interceptor::generateFeatureStateEvent()
199 DocumentHolder
* pTmpDocH
= NULL
;
200 uno::Reference
< uno::XInterface
> xLock
;
202 osl::MutexGuard
aGuard(m_aMutex
);
203 xLock
= m_xDocHLocker
.get();
210 aTitle
= pTmpDocH
->getTitle();
212 for(int i
= 0; i
< IUL
; ++i
)
214 if( i
== 1 || (m_bLink
&& i
!= 5) )
217 cppu::OInterfaceContainerHelper
* pICH
=
218 m_pStatCL
->getContainer(m_aInterceptedURL
[i
]);
219 uno::Sequence
<uno::Reference
<uno::XInterface
> > aSeq
;
221 aSeq
= pICH
->getElements();
222 if(!aSeq
.getLength())
225 frame::FeatureStateEvent aStateEvent
;
226 aStateEvent
.IsEnabled
= sal_True
;
227 aStateEvent
.Requery
= sal_False
;
231 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
232 aStateEvent
.FeatureDescriptor
= "Update";
233 aStateEvent
.State
<<= (OUString("($1) ") + aTitle
);
238 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
239 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
240 aStateEvent
.State
<<= (OUString("($3)"));
244 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
245 aStateEvent
.FeatureDescriptor
= "Close and Return";
246 aStateEvent
.State
<<= (OUString("($2) ") + aTitle
);
250 for(sal_Int32 k
= 0; k
< aSeq
.getLength(); ++k
)
252 uno::Reference
<frame::XStatusListener
>
253 Control(aSeq
[k
],uno::UNO_QUERY
);
255 Control
->statusChanged(aStateEvent
);
264 Interceptor::addStatusListener(
265 const uno::Reference
<
266 frame::XStatusListener
>& Control
,
267 const util::URL
& URL
)
269 uno::RuntimeException
275 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
277 DocumentHolder
* pTmpDocH
= NULL
;
278 uno::Reference
< uno::XInterface
> xLock
;
280 osl::MutexGuard
aGuard(m_aMutex
);
281 xLock
= m_xDocHLocker
.get();
288 aTitle
= pTmpDocH
->getTitle();
290 frame::FeatureStateEvent aStateEvent
;
291 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
292 aStateEvent
.FeatureDescriptor
= "Update";
293 aStateEvent
.IsEnabled
= sal_True
;
294 aStateEvent
.Requery
= sal_False
;
295 aStateEvent
.State
<<= (OUString("($1) ") + aTitle
);
296 Control
->statusChanged(aStateEvent
);
299 osl::MutexGuard
aGuard(m_aMutex
);
302 new StatusChangeListenerContainer(m_aMutex
);
305 m_pStatCL
->addInterface(URL
.Complete
,Control
);
311 && ( URL
.Complete
== m_aInterceptedURL
[i
] ||
312 URL
.Complete
== m_aInterceptedURL
[++i
] ||
313 URL
.Complete
== m_aInterceptedURL
[++i
] ) )
314 { // Close and return
315 DocumentHolder
* pTmpDocH
= NULL
;
316 uno::Reference
< uno::XInterface
> xLock
;
318 osl::MutexGuard
aGuard(m_aMutex
);
319 xLock
= m_xDocHLocker
.get();
326 aTitle
= pTmpDocH
->getTitle();
328 frame::FeatureStateEvent aStateEvent
;
329 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
330 aStateEvent
.FeatureDescriptor
= "Close and Return";
331 aStateEvent
.IsEnabled
= sal_True
;
332 aStateEvent
.Requery
= sal_False
;
333 aStateEvent
.State
<<= (OUString("($2) ") + aTitle
);
334 Control
->statusChanged(aStateEvent
);
338 osl::MutexGuard
aGuard(m_aMutex
);
341 new StatusChangeListenerContainer(m_aMutex
);
344 m_pStatCL
->addInterface(URL
.Complete
,Control
);
348 if(URL
.Complete
== m_aInterceptedURL
[5])
350 frame::FeatureStateEvent aStateEvent
;
351 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
352 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
353 aStateEvent
.IsEnabled
= sal_True
;
354 aStateEvent
.Requery
= sal_False
;
355 aStateEvent
.State
<<= (OUString("($3)"));
356 Control
->statusChanged(aStateEvent
);
359 osl::MutexGuard
aGuard(m_aMutex
);
362 new StatusChangeListenerContainer(m_aMutex
);
365 m_pStatCL
->addInterface(URL
.Complete
,Control
);
373 Interceptor::removeStatusListener(
374 const uno::Reference
<
375 frame::XStatusListener
>& Control
,
376 const util::URL
& URL
)
378 uno::RuntimeException
381 if(!(Control
.is() && m_pStatCL
))
384 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
391 uno::Sequence
< OUString
>
393 Interceptor::getInterceptedURLs( )
395 uno::RuntimeException
398 // now implemented as update
401 uno::Sequence
< OUString
> aResult( 2 );
402 aResult
[0] = m_aInterceptedURL
[1];
403 aResult
[1] = m_aInterceptedURL
[5];
408 return m_aInterceptedURL
;
414 uno::Reference
< frame::XDispatch
> SAL_CALL
415 Interceptor::queryDispatch(
416 const util::URL
& URL
,
417 const OUString
& TargetFrameName
,
418 sal_Int32 SearchFlags
)
420 uno::RuntimeException
423 osl::MutexGuard
aGuard(m_aMutex
);
424 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
425 return (frame::XDispatch
*)this;
426 else if(URL
.Complete
== m_aInterceptedURL
[1])
427 return (frame::XDispatch
*)0 ;
428 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[2] )
429 return (frame::XDispatch
*)this;
430 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[3] )
431 return (frame::XDispatch
*)this;
432 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[4] )
433 return (frame::XDispatch
*)this;
434 else if(URL
.Complete
== m_aInterceptedURL
[5])
435 return (frame::XDispatch
*)this;
437 if(m_xSlaveDispatchProvider
.is())
438 return m_xSlaveDispatchProvider
->queryDispatch(
439 URL
,TargetFrameName
,SearchFlags
);
441 return uno::Reference
<frame::XDispatch
>(0);
445 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SAL_CALL
446 Interceptor::queryDispatches(
447 const uno::Sequence
<frame::DispatchDescriptor
>& Requests
)
449 uno::RuntimeException
452 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aRet
;
453 osl::MutexGuard
aGuard(m_aMutex
);
454 if(m_xSlaveDispatchProvider
.is())
455 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
457 aRet
.realloc(Requests
.getLength());
459 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
460 if ( !m_bLink
&& m_aInterceptedURL
[0] == Requests
[i
].FeatureURL
.Complete
)
461 aRet
[i
] = (frame::XDispatch
*) this;
462 else if(m_aInterceptedURL
[1] == Requests
[i
].FeatureURL
.Complete
)
463 aRet
[i
] = (frame::XDispatch
*) 0;
464 else if( !m_bLink
&& m_aInterceptedURL
[2] == Requests
[i
].FeatureURL
.Complete
)
465 aRet
[i
] = (frame::XDispatch
*) this;
466 else if( !m_bLink
&& m_aInterceptedURL
[3] == Requests
[i
].FeatureURL
.Complete
)
467 aRet
[i
] = (frame::XDispatch
*) this;
468 else if( !m_bLink
&& m_aInterceptedURL
[4] == Requests
[i
].FeatureURL
.Complete
)
469 aRet
[i
] = (frame::XDispatch
*) this;
470 else if(m_aInterceptedURL
[5] == Requests
[i
].FeatureURL
.Complete
)
471 aRet
[i
] = (frame::XDispatch
*) this;
477 //XDispatchProviderInterceptor
479 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
480 Interceptor::getSlaveDispatchProvider( )
482 uno::RuntimeException
485 osl::MutexGuard
aGuard(m_aMutex
);
486 return m_xSlaveDispatchProvider
;
490 Interceptor::setSlaveDispatchProvider(
491 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
493 uno::RuntimeException
496 osl::MutexGuard
aGuard(m_aMutex
);
497 m_xSlaveDispatchProvider
= NewDispatchProvider
;
501 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
502 Interceptor::getMasterDispatchProvider( )
504 uno::RuntimeException
507 osl::MutexGuard
aGuard(m_aMutex
);
508 return m_xMasterDispatchProvider
;
513 Interceptor::setMasterDispatchProvider(
514 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
516 uno::RuntimeException
519 osl::MutexGuard
aGuard(m_aMutex
);
520 m_xMasterDispatchProvider
= NewSupplier
;
523 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */