Use o3tl::convert in Math
[LibreOffice.git] / embedserv / source / embed / intercept.cxx
blobec10c642657b82b5de1369c29189d118d4fda873
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
29 #define IUL 6
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>
42 public:
43 explicit StatusChangeListenerContainer(osl::Mutex& aMutex)
44 : comphelper::OMultiTypeInterfaceContainerHelperVar2<OUString>(aMutex)
50 void
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 );
64 void
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 );
85 if(m_pStatCL)
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,
96 bool bLink )
97 : m_xOleAccess( xOleAccess ),
98 m_xDocHLocker( static_cast< ::cppu::OWeakObject* >( pDocH ) ),
99 m_pDocH(pDocH),
100 m_pDisposeEventListeners(nullptr),
101 m_pStatCL(nullptr),
102 m_bLink( bLink )
107 Interceptor::~Interceptor()
109 delete m_pDisposeEventListeners;
110 delete m_pStatCL;
112 DocumentHolder* pTmpDocH = nullptr;
113 uno::Reference< uno::XInterface > xLock;
115 osl::MutexGuard aGuard(m_aMutex);
116 xLock = m_xDocHLocker.get();
117 if ( xLock.is() )
118 pTmpDocH = m_pDocH;
121 if ( pTmpDocH )
122 pTmpDocH->ClearInterceptor();
125 void Interceptor::DisconnectDocHolder()
127 osl::MutexGuard aGuard(m_aMutex);
128 m_xDocHLocker.clear();
129 m_pDocH = nullptr;
130 m_xOleAccess = nullptr;
133 //XDispatch
134 void SAL_CALL
135 Interceptor::dispatch(
136 const util::URL& URL,
137 const uno::Sequence<
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();
153 else if(!m_bLink
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;
161 sal_Int32 nInd = 0;
163 while( nInd < aNewArgs.getLength() )
165 if ( aNewArgs[nInd].Name == "SaveTo" )
167 aNewArgs.getArray()[nInd].Value <<= true;
168 break;
170 nInd++;
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(
182 URL, "_self", 0 );
183 if ( xDispatch.is() )
184 xDispatch->dispatch( URL, aNewArgs );
191 void Interceptor::generateFeatureStateEvent()
193 if( m_pStatCL )
195 DocumentHolder* pTmpDocH = nullptr;
196 uno::Reference< uno::XInterface > xLock;
198 osl::MutexGuard aGuard(m_aMutex);
199 xLock = m_xDocHLocker.get();
200 if ( xLock.is() )
201 pTmpDocH = m_pDocH;
204 OUString aTitle;
205 if ( pTmpDocH )
206 aTitle = pTmpDocH->getTitle();
208 for(int i = 0; i < IUL; ++i)
210 if( i == 1 || (m_bLink && i != 5) )
211 continue;
213 comphelper::OInterfaceContainerHelper2* pICH =
214 m_pStatCL->getContainer(m_aInterceptedURL[i]);
215 if(!pICH)
216 continue;
217 std::vector<uno::Reference<uno::XInterface> > aSeq = pICH->getElements();
218 if(aSeq.empty())
219 continue;
221 frame::FeatureStateEvent aStateEvent;
222 aStateEvent.IsEnabled = true;
223 aStateEvent.Requery = false;
224 if(i == 0)
227 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
228 aStateEvent.FeatureDescriptor = "Update";
229 aStateEvent.State <<= "($1) " + aTitle;
232 else if ( i == 5 )
234 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
235 aStateEvent.FeatureDescriptor = "SaveCopyTo";
236 aStateEvent.State <<= OUString("($3)");
238 else
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);
249 if(Control.is())
250 Control->statusChanged(aStateEvent);
258 void SAL_CALL
259 Interceptor::addStatusListener(
260 const uno::Reference<
261 frame::XStatusListener >& Control,
262 const util::URL& URL )
264 if(!Control.is())
265 return;
267 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
268 { // Save
269 DocumentHolder* pTmpDocH = nullptr;
270 uno::Reference< uno::XInterface > xLock;
272 osl::MutexGuard aGuard(m_aMutex);
273 xLock = m_xDocHLocker.get();
274 if ( xLock.is() )
275 pTmpDocH = m_pDocH;
278 OUString aTitle;
279 if ( pTmpDocH )
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);
292 if(!m_pStatCL)
293 m_pStatCL =
294 new StatusChangeListenerContainer(m_aMutex);
297 m_pStatCL->addInterface(URL.Complete,Control);
298 return;
301 sal_Int32 i = 2;
302 if ( !m_bLink
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();
312 if ( xLock.is() )
313 pTmpDocH = m_pDocH;
316 OUString aTitle;
317 if ( pTmpDocH )
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);
331 if(!m_pStatCL)
332 m_pStatCL =
333 new StatusChangeListenerContainer(m_aMutex);
336 m_pStatCL->addInterface(URL.Complete,Control);
337 return;
340 if(URL.Complete == m_aInterceptedURL[5])
341 { // SaveAs
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);
352 if(!m_pStatCL)
353 m_pStatCL =
354 new StatusChangeListenerContainer(m_aMutex);
357 m_pStatCL->addInterface(URL.Complete,Control);
358 return;
364 void SAL_CALL
365 Interceptor::removeStatusListener(
366 const uno::Reference<
367 frame::XStatusListener >& Control,
368 const util::URL& URL )
370 if(!(Control.is() && m_pStatCL))
371 return;
372 else {
373 m_pStatCL->removeInterface(URL.Complete,Control);
374 return;
379 //XInterceptorInfo
380 uno::Sequence< OUString >
381 SAL_CALL
382 Interceptor::getInterceptedURLs( )
384 // now implemented as update
385 if ( m_bLink )
386 return { m_aInterceptedURL[1], m_aInterceptedURL[5] };
388 return m_aInterceptedURL;
392 // XDispatchProvider
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])
404 return nullptr;
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);
413 else {
414 if(m_xSlaveDispatchProvider.is())
415 return m_xSlaveDispatchProvider->queryDispatch(
416 URL,TargetFrameName,SearchFlags);
417 else
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);
430 else
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);
447 return aRet;
451 //XDispatchProviderInterceptor
453 uno::Reference< frame::XDispatchProvider > SAL_CALL
454 Interceptor::getSlaveDispatchProvider( )
456 osl::MutexGuard aGuard(m_aMutex);
457 return m_xSlaveDispatchProvider;
460 void SAL_CALL
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;
477 void SAL_CALL
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: */