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 <comphelper/multiinterfacecontainer2.hxx>
22 #include <embeddoc.hxx>
23 #include <docholder.hxx>
24 #include <intercept.hxx>
26 using namespace ::com::sun::star
;
31 constexpr OUStringLiteral IU0
= u
".uno:Save";
32 constexpr OUStringLiteral IU1
= u
".uno:SaveAll";
33 constexpr OUStringLiteral IU2
= u
".uno:CloseDoc";
34 constexpr OUStringLiteral IU3
= u
".uno:CloseWin";
35 constexpr OUStringLiteral IU4
= u
".uno:CloseFrame";
36 constexpr OUStringLiteral IU5
= u
".uno:SaveAs";
37 const uno::Sequence
< OUString
> Interceptor::m_aInterceptedURL
{ IU0
, IU1
, IU2
, IU3
, IU4
, IU5
};
39 class StatusChangeListenerContainer
40 : public comphelper::OMultiTypeInterfaceContainerHelperVar2
<OUString
>
43 explicit StatusChangeListenerContainer(osl::Mutex
& aMutex
)
44 : comphelper::OMultiTypeInterfaceContainerHelperVar2
<OUString
>(aMutex
)
51 Interceptor::addEventListener(
52 const uno::Reference
<lang::XEventListener
>& Listener
)
54 osl::MutexGuard
aGuard( m_aMutex
);
56 if ( ! m_pDisposeEventListeners
)
57 m_pDisposeEventListeners
=
58 new comphelper::OInterfaceContainerHelper2( m_aMutex
);
60 m_pDisposeEventListeners
->addInterface( Listener
);
65 Interceptor::removeEventListener(
66 const uno::Reference
< lang::XEventListener
>& Listener
)
68 osl::MutexGuard
aGuard( m_aMutex
);
70 if ( m_pDisposeEventListeners
)
71 m_pDisposeEventListeners
->removeInterface( Listener
);
75 void Interceptor::dispose()
77 lang::EventObject aEvt
;
78 aEvt
.Source
= static_cast< frame::XDispatch
* >( this );
80 osl::MutexGuard
aGuard(m_aMutex
);
82 if ( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
83 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
86 m_pStatCL
->disposeAndClear( aEvt
);
88 m_xSlaveDispatchProvider
= nullptr;
89 m_xMasterDispatchProvider
= nullptr;
93 Interceptor::Interceptor(
94 const ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
>& xOleAccess
,
95 DocumentHolder
* pDocH
,
97 : m_xOleAccess( xOleAccess
),
98 m_xDocHLocker( static_cast< ::cppu::OWeakObject
* >( pDocH
) ),
100 m_pDisposeEventListeners(nullptr),
107 Interceptor::~Interceptor()
109 delete m_pDisposeEventListeners
;
112 DocumentHolder
* pTmpDocH
= nullptr;
113 uno::Reference
< uno::XInterface
> xLock
;
115 osl::MutexGuard
aGuard(m_aMutex
);
116 xLock
= m_xDocHLocker
.get();
122 pTmpDocH
->ClearInterceptor();
125 void Interceptor::DisconnectDocHolder()
127 osl::MutexGuard
aGuard(m_aMutex
);
128 m_xDocHLocker
.clear();
130 m_xOleAccess
= nullptr;
135 Interceptor::dispatch(
136 const util::URL
& URL
,
138 beans::PropertyValue
>& Arguments
)
140 ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
> xOleAccess
;
142 osl::MutexGuard
aGuard(m_aMutex
);
143 xOleAccess
= m_xOleAccess
;
146 if ( xOleAccess
.is() )
148 LockedEmbedDocument_Impl aDocLock
= xOleAccess
->GetEmbedDocument();
149 if ( aDocLock
.GetEmbedDocument() )
151 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0])
152 aDocLock
.GetEmbedDocument()->SaveObject();
154 && ( URL
.Complete
== m_aInterceptedURL
[2] ||
155 URL
.Complete
== m_aInterceptedURL
[3] ||
156 URL
.Complete
== m_aInterceptedURL
[4] ) )
157 aDocLock
.GetEmbedDocument()->Close( 0 );
158 else if ( URL
.Complete
== m_aInterceptedURL
[5] )
160 uno::Sequence
< beans::PropertyValue
> aNewArgs
= Arguments
;
163 while( nInd
< aNewArgs
.getLength() )
165 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
167 aNewArgs
.getArray()[nInd
].Value
<<= true;
173 if ( nInd
== aNewArgs
.getLength() )
175 aNewArgs
.realloc( nInd
+ 1 );
176 auto pNewArgs
= aNewArgs
.getArray();
177 pNewArgs
[nInd
].Name
= "SaveTo";
178 pNewArgs
[nInd
].Value
<<= true;
181 uno::Reference
< frame::XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
183 if ( xDispatch
.is() )
184 xDispatch
->dispatch( URL
, aNewArgs
);
191 void Interceptor::generateFeatureStateEvent()
195 DocumentHolder
* pTmpDocH
= nullptr;
196 uno::Reference
< uno::XInterface
> xLock
;
198 osl::MutexGuard
aGuard(m_aMutex
);
199 xLock
= m_xDocHLocker
.get();
206 aTitle
= pTmpDocH
->getTitle();
208 for(int i
= 0; i
< IUL
; ++i
)
210 if( i
== 1 || (m_bLink
&& i
!= 5) )
213 comphelper::OInterfaceContainerHelper2
* pICH
=
214 m_pStatCL
->getContainer(m_aInterceptedURL
[i
]);
217 std::vector
<uno::Reference
<uno::XInterface
> > aSeq
= pICH
->getElements();
221 frame::FeatureStateEvent aStateEvent
;
222 aStateEvent
.IsEnabled
= true;
223 aStateEvent
.Requery
= false;
227 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
228 aStateEvent
.FeatureDescriptor
= "Update";
229 aStateEvent
.State
<<= "($1) " + aTitle
;
234 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
235 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
236 aStateEvent
.State
<<= OUString("($3)");
240 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
241 aStateEvent
.FeatureDescriptor
= "Close and Return";
242 aStateEvent
.State
<<= "($2) " + aTitle
;
246 for(uno::Reference
<uno::XInterface
> const & k
: std::as_const(aSeq
))
248 uno::Reference
<frame::XStatusListener
> Control(k
,uno::UNO_QUERY
);
250 Control
->statusChanged(aStateEvent
);
259 Interceptor::addStatusListener(
260 const uno::Reference
<
261 frame::XStatusListener
>& Control
,
262 const util::URL
& URL
)
267 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
269 DocumentHolder
* pTmpDocH
= nullptr;
270 uno::Reference
< uno::XInterface
> xLock
;
272 osl::MutexGuard
aGuard(m_aMutex
);
273 xLock
= m_xDocHLocker
.get();
280 aTitle
= pTmpDocH
->getTitle();
282 frame::FeatureStateEvent aStateEvent
;
283 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
284 aStateEvent
.FeatureDescriptor
= "Update";
285 aStateEvent
.IsEnabled
= true;
286 aStateEvent
.Requery
= false;
287 aStateEvent
.State
<<= "($1) " + aTitle
;
288 Control
->statusChanged(aStateEvent
);
291 osl::MutexGuard
aGuard(m_aMutex
);
294 new StatusChangeListenerContainer(m_aMutex
);
297 m_pStatCL
->addInterface(URL
.Complete
,Control
);
303 && ( URL
.Complete
== m_aInterceptedURL
[i
] ||
304 URL
.Complete
== m_aInterceptedURL
[++i
] ||
305 URL
.Complete
== m_aInterceptedURL
[++i
] ) )
306 { // Close and return
307 DocumentHolder
* pTmpDocH
= nullptr;
308 uno::Reference
< uno::XInterface
> xLock
;
310 osl::MutexGuard
aGuard(m_aMutex
);
311 xLock
= m_xDocHLocker
.get();
318 aTitle
= pTmpDocH
->getTitle();
320 frame::FeatureStateEvent aStateEvent
;
321 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
322 aStateEvent
.FeatureDescriptor
= "Close and Return";
323 aStateEvent
.IsEnabled
= true;
324 aStateEvent
.Requery
= false;
325 aStateEvent
.State
<<= "($2) " + aTitle
;
326 Control
->statusChanged(aStateEvent
);
330 osl::MutexGuard
aGuard(m_aMutex
);
333 new StatusChangeListenerContainer(m_aMutex
);
336 m_pStatCL
->addInterface(URL
.Complete
,Control
);
340 if(URL
.Complete
== m_aInterceptedURL
[5])
342 frame::FeatureStateEvent aStateEvent
;
343 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
344 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
345 aStateEvent
.IsEnabled
= true;
346 aStateEvent
.Requery
= false;
347 aStateEvent
.State
<<= OUString("($3)");
348 Control
->statusChanged(aStateEvent
);
351 osl::MutexGuard
aGuard(m_aMutex
);
354 new StatusChangeListenerContainer(m_aMutex
);
357 m_pStatCL
->addInterface(URL
.Complete
,Control
);
365 Interceptor::removeStatusListener(
366 const uno::Reference
<
367 frame::XStatusListener
>& Control
,
368 const util::URL
& URL
)
370 if(!(Control
.is() && m_pStatCL
))
373 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
380 uno::Sequence
< OUString
>
382 Interceptor::getInterceptedURLs( )
384 // now implemented as update
386 return { m_aInterceptedURL
[1], m_aInterceptedURL
[5] };
388 return m_aInterceptedURL
;
394 uno::Reference
< frame::XDispatch
> SAL_CALL
395 Interceptor::queryDispatch(
396 const util::URL
& URL
,
397 const OUString
& TargetFrameName
,
398 sal_Int32 SearchFlags
)
400 osl::MutexGuard
aGuard(m_aMutex
);
401 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
402 return static_cast<frame::XDispatch
*>(this);
403 else if(URL
.Complete
== m_aInterceptedURL
[1])
405 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[2] )
406 return static_cast<frame::XDispatch
*>(this);
407 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[3] )
408 return static_cast<frame::XDispatch
*>(this);
409 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[4] )
410 return static_cast<frame::XDispatch
*>(this);
411 else if(URL
.Complete
== m_aInterceptedURL
[5])
412 return static_cast<frame::XDispatch
*>(this);
414 if(m_xSlaveDispatchProvider
.is())
415 return m_xSlaveDispatchProvider
->queryDispatch(
416 URL
,TargetFrameName
,SearchFlags
);
418 return uno::Reference
<frame::XDispatch
>(nullptr);
422 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SAL_CALL
423 Interceptor::queryDispatches(
424 const uno::Sequence
<frame::DispatchDescriptor
>& Requests
)
426 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aRet
;
427 osl::MutexGuard
aGuard(m_aMutex
);
428 if(m_xSlaveDispatchProvider
.is())
429 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
431 aRet
.realloc(Requests
.getLength());
432 auto aRetRange
= asNonConstRange(aRet
);
433 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
434 if ( !m_bLink
&& m_aInterceptedURL
[0] == Requests
[i
].FeatureURL
.Complete
)
435 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
436 else if(m_aInterceptedURL
[1] == Requests
[i
].FeatureURL
.Complete
)
437 aRetRange
[i
] = nullptr;
438 else if( !m_bLink
&& m_aInterceptedURL
[2] == Requests
[i
].FeatureURL
.Complete
)
439 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
440 else if( !m_bLink
&& m_aInterceptedURL
[3] == Requests
[i
].FeatureURL
.Complete
)
441 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
442 else if( !m_bLink
&& m_aInterceptedURL
[4] == Requests
[i
].FeatureURL
.Complete
)
443 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
444 else if(m_aInterceptedURL
[5] == Requests
[i
].FeatureURL
.Complete
)
445 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
451 //XDispatchProviderInterceptor
453 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
454 Interceptor::getSlaveDispatchProvider( )
456 osl::MutexGuard
aGuard(m_aMutex
);
457 return m_xSlaveDispatchProvider
;
461 Interceptor::setSlaveDispatchProvider(
462 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
464 osl::MutexGuard
aGuard(m_aMutex
);
465 m_xSlaveDispatchProvider
= NewDispatchProvider
;
469 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
470 Interceptor::getMasterDispatchProvider( )
472 osl::MutexGuard
aGuard(m_aMutex
);
473 return m_xMasterDispatchProvider
;
478 Interceptor::setMasterDispatchProvider(
479 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
481 osl::MutexGuard
aGuard(m_aMutex
);
482 m_xMasterDispatchProvider
= NewSupplier
;
485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */