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
;
30 constexpr OUString IU0
= u
".uno:Save"_ustr
;
31 constexpr OUString IU1
= u
".uno:SaveAll"_ustr
;
32 constexpr OUString IU2
= u
".uno:CloseDoc"_ustr
;
33 constexpr OUString IU3
= u
".uno:CloseWin"_ustr
;
34 constexpr OUString IU4
= u
".uno:CloseFrame"_ustr
;
35 constexpr OUString IU5
= u
".uno:SaveAs"_ustr
;
36 const uno::Sequence
< OUString
> Interceptor::m_aInterceptedURL
{ IU0
, IU1
, IU2
, IU3
, IU4
, IU5
};
41 Interceptor::addEventListener(
42 const uno::Reference
<lang::XEventListener
>& Listener
)
44 osl::MutexGuard
aGuard( m_aMutex
);
46 if ( ! m_pDisposeEventListeners
)
47 m_pDisposeEventListeners
=
48 new comphelper::OInterfaceContainerHelper2( m_aMutex
);
50 m_pDisposeEventListeners
->addInterface( Listener
);
55 Interceptor::removeEventListener(
56 const uno::Reference
< lang::XEventListener
>& Listener
)
58 osl::MutexGuard
aGuard( m_aMutex
);
60 if ( m_pDisposeEventListeners
)
61 m_pDisposeEventListeners
->removeInterface( Listener
);
65 void Interceptor::dispose()
67 lang::EventObject aEvt
;
68 aEvt
.Source
= static_cast< frame::XDispatch
* >( this );
70 osl::MutexGuard
aGuard(m_aMutex
);
72 if ( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
73 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
76 m_pStatCL
->disposeAndClear( aEvt
);
78 m_xSlaveDispatchProvider
= nullptr;
79 m_xMasterDispatchProvider
= nullptr;
83 Interceptor::Interceptor(
84 const ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
>& xOleAccess
,
85 DocumentHolder
* pDocH
,
87 : m_xOleAccess( xOleAccess
),
88 m_xDocHLocker( cppu::getXWeak( pDocH
) ),
90 m_pDisposeEventListeners(nullptr),
97 Interceptor::~Interceptor()
99 delete m_pDisposeEventListeners
;
102 DocumentHolder
* pTmpDocH
= nullptr;
103 uno::Reference
< uno::XInterface
> xLock
;
105 osl::MutexGuard
aGuard(m_aMutex
);
106 xLock
= m_xDocHLocker
.get();
112 pTmpDocH
->ClearInterceptor();
115 void Interceptor::DisconnectDocHolder()
117 osl::MutexGuard
aGuard(m_aMutex
);
118 m_xDocHLocker
.clear();
120 m_xOleAccess
= nullptr;
125 Interceptor::dispatch(
126 const util::URL
& URL
,
128 beans::PropertyValue
>& Arguments
)
130 ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
> xOleAccess
;
132 osl::MutexGuard
aGuard(m_aMutex
);
133 xOleAccess
= m_xOleAccess
;
136 if ( xOleAccess
.is() )
138 LockedEmbedDocument_Impl aDocLock
= xOleAccess
->GetEmbedDocument();
139 if ( aDocLock
.GetEmbedDocument() )
141 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0])
142 aDocLock
.GetEmbedDocument()->SaveObject();
144 && ( URL
.Complete
== m_aInterceptedURL
[2] ||
145 URL
.Complete
== m_aInterceptedURL
[3] ||
146 URL
.Complete
== m_aInterceptedURL
[4] ) )
147 aDocLock
.GetEmbedDocument()->Close( 0 );
148 else if ( URL
.Complete
== m_aInterceptedURL
[5] )
150 uno::Sequence
< beans::PropertyValue
> aNewArgs
= Arguments
;
153 while( nInd
< aNewArgs
.getLength() )
155 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
157 aNewArgs
.getArray()[nInd
].Value
<<= true;
163 if ( nInd
== aNewArgs
.getLength() )
165 aNewArgs
.realloc( nInd
+ 1 );
166 auto pNewArgs
= aNewArgs
.getArray();
167 pNewArgs
[nInd
].Name
= "SaveTo";
168 pNewArgs
[nInd
].Value
<<= true;
171 uno::Reference
< frame::XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
173 if ( xDispatch
.is() )
174 xDispatch
->dispatch( URL
, aNewArgs
);
181 void Interceptor::generateFeatureStateEvent()
185 DocumentHolder
* pTmpDocH
= nullptr;
186 uno::Reference
< uno::XInterface
> xLock
;
188 osl::MutexGuard
aGuard(m_aMutex
);
189 xLock
= m_xDocHLocker
.get();
196 aTitle
= pTmpDocH
->getTitle();
198 for(int i
= 0; i
< IUL
; ++i
)
200 if( i
== 1 || (m_bLink
&& i
!= 5) )
203 comphelper::OInterfaceContainerHelper3
<css::frame::XStatusListener
>* pICH
=
204 m_pStatCL
->getContainer(m_aInterceptedURL
[i
]);
207 std::vector
<uno::Reference
<css::frame::XStatusListener
> > aSeq
= pICH
->getElements();
211 frame::FeatureStateEvent aStateEvent
;
212 aStateEvent
.IsEnabled
= true;
213 aStateEvent
.Requery
= false;
217 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
218 aStateEvent
.FeatureDescriptor
= "Update";
219 aStateEvent
.State
<<= "($1) " + aTitle
;
224 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
225 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
226 aStateEvent
.State
<<= OUString("($3)");
230 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
231 aStateEvent
.FeatureDescriptor
= "Close and Return";
232 aStateEvent
.State
<<= "($2) " + aTitle
;
236 for(uno::Reference
<css::frame::XStatusListener
> const & control
: std::as_const(aSeq
))
237 control
->statusChanged(aStateEvent
);
244 Interceptor::addStatusListener(
245 const uno::Reference
<
246 frame::XStatusListener
>& Control
,
247 const util::URL
& URL
)
252 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
254 DocumentHolder
* pTmpDocH
= nullptr;
255 uno::Reference
< uno::XInterface
> xLock
;
257 osl::MutexGuard
aGuard(m_aMutex
);
258 xLock
= m_xDocHLocker
.get();
265 aTitle
= pTmpDocH
->getTitle();
267 frame::FeatureStateEvent aStateEvent
;
268 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[0];
269 aStateEvent
.FeatureDescriptor
= "Update";
270 aStateEvent
.IsEnabled
= true;
271 aStateEvent
.Requery
= false;
272 aStateEvent
.State
<<= "($1) " + aTitle
;
273 Control
->statusChanged(aStateEvent
);
276 osl::MutexGuard
aGuard(m_aMutex
);
279 new StatusChangeListenerContainer(m_aMutex
);
282 m_pStatCL
->addInterface(URL
.Complete
,Control
);
288 && ( URL
.Complete
== m_aInterceptedURL
[i
] ||
289 URL
.Complete
== m_aInterceptedURL
[++i
] ||
290 URL
.Complete
== m_aInterceptedURL
[++i
] ) )
291 { // Close and return
292 DocumentHolder
* pTmpDocH
= nullptr;
293 uno::Reference
< uno::XInterface
> xLock
;
295 osl::MutexGuard
aGuard(m_aMutex
);
296 xLock
= m_xDocHLocker
.get();
303 aTitle
= pTmpDocH
->getTitle();
305 frame::FeatureStateEvent aStateEvent
;
306 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
307 aStateEvent
.FeatureDescriptor
= "Close and Return";
308 aStateEvent
.IsEnabled
= true;
309 aStateEvent
.Requery
= false;
310 aStateEvent
.State
<<= "($2) " + aTitle
;
311 Control
->statusChanged(aStateEvent
);
315 osl::MutexGuard
aGuard(m_aMutex
);
318 new StatusChangeListenerContainer(m_aMutex
);
321 m_pStatCL
->addInterface(URL
.Complete
,Control
);
325 if(URL
.Complete
== m_aInterceptedURL
[5])
327 frame::FeatureStateEvent aStateEvent
;
328 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[5];
329 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
330 aStateEvent
.IsEnabled
= true;
331 aStateEvent
.Requery
= false;
332 aStateEvent
.State
<<= OUString("($3)");
333 Control
->statusChanged(aStateEvent
);
336 osl::MutexGuard
aGuard(m_aMutex
);
339 new StatusChangeListenerContainer(m_aMutex
);
342 m_pStatCL
->addInterface(URL
.Complete
,Control
);
350 Interceptor::removeStatusListener(
351 const uno::Reference
<
352 frame::XStatusListener
>& Control
,
353 const util::URL
& URL
)
355 if(!(Control
.is() && m_pStatCL
))
358 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
365 uno::Sequence
< OUString
>
367 Interceptor::getInterceptedURLs( )
369 // now implemented as update
371 return { m_aInterceptedURL
[1], m_aInterceptedURL
[5] };
373 return m_aInterceptedURL
;
379 uno::Reference
< frame::XDispatch
> SAL_CALL
380 Interceptor::queryDispatch(
381 const util::URL
& URL
,
382 const OUString
& TargetFrameName
,
383 sal_Int32 SearchFlags
)
385 osl::MutexGuard
aGuard(m_aMutex
);
386 if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[0] )
387 return static_cast<frame::XDispatch
*>(this);
388 else if(URL
.Complete
== m_aInterceptedURL
[1])
390 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[2] )
391 return static_cast<frame::XDispatch
*>(this);
392 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[3] )
393 return static_cast<frame::XDispatch
*>(this);
394 else if( !m_bLink
&& URL
.Complete
== m_aInterceptedURL
[4] )
395 return static_cast<frame::XDispatch
*>(this);
396 else if(URL
.Complete
== m_aInterceptedURL
[5])
397 return static_cast<frame::XDispatch
*>(this);
399 if(m_xSlaveDispatchProvider
.is())
400 return m_xSlaveDispatchProvider
->queryDispatch(
401 URL
,TargetFrameName
,SearchFlags
);
403 return uno::Reference
<frame::XDispatch
>(nullptr);
407 uno::Sequence
< uno::Reference
< frame::XDispatch
> > SAL_CALL
408 Interceptor::queryDispatches(
409 const uno::Sequence
<frame::DispatchDescriptor
>& Requests
)
411 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aRet
;
412 osl::MutexGuard
aGuard(m_aMutex
);
413 if(m_xSlaveDispatchProvider
.is())
414 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
416 aRet
.realloc(Requests
.getLength());
417 auto aRetRange
= asNonConstRange(aRet
);
418 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
419 if ( !m_bLink
&& m_aInterceptedURL
[0] == Requests
[i
].FeatureURL
.Complete
)
420 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
421 else if(m_aInterceptedURL
[1] == Requests
[i
].FeatureURL
.Complete
)
422 aRetRange
[i
] = nullptr;
423 else if( !m_bLink
&& m_aInterceptedURL
[2] == Requests
[i
].FeatureURL
.Complete
)
424 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
425 else if( !m_bLink
&& m_aInterceptedURL
[3] == Requests
[i
].FeatureURL
.Complete
)
426 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
427 else if( !m_bLink
&& m_aInterceptedURL
[4] == Requests
[i
].FeatureURL
.Complete
)
428 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
429 else if(m_aInterceptedURL
[5] == Requests
[i
].FeatureURL
.Complete
)
430 aRetRange
[i
] = static_cast<frame::XDispatch
*>(this);
436 //XDispatchProviderInterceptor
438 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
439 Interceptor::getSlaveDispatchProvider( )
441 osl::MutexGuard
aGuard(m_aMutex
);
442 return m_xSlaveDispatchProvider
;
446 Interceptor::setSlaveDispatchProvider(
447 const uno::Reference
< frame::XDispatchProvider
>& NewDispatchProvider
)
449 osl::MutexGuard
aGuard(m_aMutex
);
450 m_xSlaveDispatchProvider
= NewDispatchProvider
;
454 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
455 Interceptor::getMasterDispatchProvider( )
457 osl::MutexGuard
aGuard(m_aMutex
);
458 return m_xMasterDispatchProvider
;
463 Interceptor::setMasterDispatchProvider(
464 const uno::Reference
< frame::XDispatchProvider
>& NewSupplier
)
466 osl::MutexGuard
aGuard(m_aMutex
);
467 m_xMasterDispatchProvider
= NewSupplier
;
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */