Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / embedserv / source / embed / intercept.cxx
blobe048eecf144610e75f48a2424a6ac28e324043bd
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>
21 #include <embeddoc.hxx>
22 #include <docholder.hxx>
23 #include <intercept.hxx>
25 using namespace ::com::sun::star;
29 #define IUL 6
33 uno::Sequence< ::rtl::OUString > Interceptor::m_aInterceptedURL(IUL);
38 struct equalOUString
40 bool operator()(
41 const rtl::OUString& rKey1,
42 const rtl::OUString& rKey2 ) const
44 return !!( rKey1 == rKey2 );
49 struct hashOUString
51 size_t operator()( const rtl::OUString& rName ) const
53 return rName.hashCode();
59 class StatusChangeListenerContainer
60 : public ::cppu::OMultiTypeInterfaceContainerHelperVar<
61 rtl::OUString,hashOUString,equalOUString>
63 public:
64 StatusChangeListenerContainer( ::osl::Mutex& aMutex )
65 : cppu::OMultiTypeInterfaceContainerHelperVar<
66 rtl::OUString,hashOUString,equalOUString>(aMutex)
72 void SAL_CALL
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 );
87 void SAL_CALL
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 );
110 if(m_pStatCL)
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,
122 sal_Bool bLink )
123 : m_xOleAccess( xOleAccess ),
124 m_xDocHLocker( static_cast< ::cppu::OWeakObject* >( pDocH ) ),
125 m_pDocH(pDocH),
126 m_pStatCL(0),
127 m_pDisposeEventListeners(0),
128 m_bLink( bLink )
130 m_aInterceptedURL[0] = rtl::OUString(
131 RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
132 m_aInterceptedURL[1] = rtl::OUString(
133 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll"));
134 m_aInterceptedURL[2] = rtl::OUString(
135 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
136 m_aInterceptedURL[3] = rtl::OUString(
137 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
138 m_aInterceptedURL[4] = rtl::OUString(
139 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
140 m_aInterceptedURL[5] = rtl::OUString(
141 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
145 Interceptor::~Interceptor()
147 if( m_pDisposeEventListeners )
148 delete m_pDisposeEventListeners;
150 if(m_pStatCL)
151 delete m_pStatCL;
153 DocumentHolder* pTmpDocH = NULL;
154 uno::Reference< uno::XInterface > xLock;
156 osl::MutexGuard aGuard(m_aMutex);
157 xLock = m_xDocHLocker.get();
158 if ( xLock.is() )
159 pTmpDocH = m_pDocH;
162 if ( pTmpDocH )
163 pTmpDocH->ClearInterceptor();
166 void Interceptor::DisconnectDocHolder()
168 osl::MutexGuard aGuard(m_aMutex);
169 m_xDocHLocker.clear();
170 m_pDocH = NULL;
171 m_xOleAccess = NULL;
174 //XDispatch
175 void SAL_CALL
176 Interceptor::dispatch(
177 const util::URL& URL,
178 const uno::Sequence<
179 beans::PropertyValue >& Arguments )
180 throw (uno::RuntimeException)
182 ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > xOleAccess;
184 osl::MutexGuard aGuard(m_aMutex);
185 xOleAccess = m_xOleAccess;
188 if ( xOleAccess.is() )
190 LockedEmbedDocument_Impl aDocLock = xOleAccess->GetEmbedDocument();
191 if ( aDocLock.GetEmbedDocument() )
193 if( !m_bLink && URL.Complete == m_aInterceptedURL[0])
194 aDocLock.GetEmbedDocument()->SaveObject();
195 else if(!m_bLink
196 && ( URL.Complete == m_aInterceptedURL[2] ||
197 URL.Complete == m_aInterceptedURL[3] ||
198 URL.Complete == m_aInterceptedURL[4] ) )
199 aDocLock.GetEmbedDocument()->Close( 0 );
200 else if ( URL.Complete == m_aInterceptedURL[5] )
202 uno::Sequence< beans::PropertyValue > aNewArgs = Arguments;
203 sal_Int32 nInd = 0;
205 while( nInd < aNewArgs.getLength() )
207 if ( aNewArgs[nInd].Name == "SaveTo" )
209 aNewArgs[nInd].Value <<= sal_True;
210 break;
212 nInd++;
215 if ( nInd == aNewArgs.getLength() )
217 aNewArgs.realloc( nInd + 1 );
218 aNewArgs[nInd].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "SaveTo" ));
219 aNewArgs[nInd].Value <<= sal_True;
222 uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
223 URL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "_self" )), 0 );
224 if ( xDispatch.is() )
225 xDispatch->dispatch( URL, aNewArgs );
232 void Interceptor::generateFeatureStateEvent()
234 if( m_pStatCL )
236 DocumentHolder* pTmpDocH = NULL;
237 uno::Reference< uno::XInterface > xLock;
239 osl::MutexGuard aGuard(m_aMutex);
240 xLock = m_xDocHLocker.get();
241 if ( xLock.is() )
242 pTmpDocH = m_pDocH;
245 ::rtl::OUString aTitle;
246 if ( pTmpDocH )
247 aTitle = pTmpDocH->getTitle();
249 for(int i = 0; i < IUL; ++i)
251 if( i == 1 || m_bLink && i != 5 )
252 continue;
254 cppu::OInterfaceContainerHelper* pICH =
255 m_pStatCL->getContainer(m_aInterceptedURL[i]);
256 uno::Sequence<uno::Reference<uno::XInterface> > aSeq;
257 if(pICH)
258 aSeq = pICH->getElements();
259 if(!aSeq.getLength())
260 continue;
262 frame::FeatureStateEvent aStateEvent;
263 aStateEvent.IsEnabled = sal_True;
264 aStateEvent.Requery = sal_False;
265 if(i == 0)
268 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
269 aStateEvent.FeatureDescriptor = rtl::OUString(
270 RTL_CONSTASCII_USTRINGPARAM("Update"));
271 aStateEvent.State <<= (rtl::OUString(
272 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
273 aTitle);
276 else if ( i == 5 )
278 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
279 aStateEvent.FeatureDescriptor = rtl::OUString(
280 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
281 aStateEvent.State <<= (rtl::OUString(
282 RTL_CONSTASCII_USTRINGPARAM("($3)")));
284 else
286 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
287 aStateEvent.FeatureDescriptor = rtl::OUString(
288 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
289 aStateEvent.State <<= (rtl::OUString(
290 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
291 aTitle);
295 for(sal_Int32 k = 0; k < aSeq.getLength(); ++k)
297 uno::Reference<frame::XStatusListener>
298 Control(aSeq[k],uno::UNO_QUERY);
299 if(Control.is())
300 Control->statusChanged(aStateEvent);
308 void SAL_CALL
309 Interceptor::addStatusListener(
310 const uno::Reference<
311 frame::XStatusListener >& Control,
312 const util::URL& URL )
313 throw (
314 uno::RuntimeException
317 if(!Control.is())
318 return;
320 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
321 { // Save
322 DocumentHolder* pTmpDocH = NULL;
323 uno::Reference< uno::XInterface > xLock;
325 osl::MutexGuard aGuard(m_aMutex);
326 xLock = m_xDocHLocker.get();
327 if ( xLock.is() )
328 pTmpDocH = m_pDocH;
331 ::rtl::OUString aTitle;
332 if ( pTmpDocH )
333 aTitle = pTmpDocH->getTitle();
335 frame::FeatureStateEvent aStateEvent;
336 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
337 aStateEvent.FeatureDescriptor = rtl::OUString(
338 RTL_CONSTASCII_USTRINGPARAM("Update"));
339 aStateEvent.IsEnabled = sal_True;
340 aStateEvent.Requery = sal_False;
341 aStateEvent.State <<= (rtl::OUString(
342 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
343 aTitle );
344 Control->statusChanged(aStateEvent);
347 osl::MutexGuard aGuard(m_aMutex);
348 if(!m_pStatCL)
349 m_pStatCL =
350 new StatusChangeListenerContainer(m_aMutex);
353 m_pStatCL->addInterface(URL.Complete,Control);
354 return;
357 sal_Int32 i = 2;
358 if ( !m_bLink
359 && ( URL.Complete == m_aInterceptedURL[i] ||
360 URL.Complete == m_aInterceptedURL[++i] ||
361 URL.Complete == m_aInterceptedURL[++i] ) )
362 { // Close and return
363 DocumentHolder* pTmpDocH = NULL;
364 uno::Reference< uno::XInterface > xLock;
366 osl::MutexGuard aGuard(m_aMutex);
367 xLock = m_xDocHLocker.get();
368 if ( xLock.is() )
369 pTmpDocH = m_pDocH;
372 ::rtl::OUString aTitle;
373 if ( pTmpDocH )
374 aTitle = pTmpDocH->getTitle();
376 frame::FeatureStateEvent aStateEvent;
377 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
378 aStateEvent.FeatureDescriptor = rtl::OUString(
379 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
380 aStateEvent.IsEnabled = sal_True;
381 aStateEvent.Requery = sal_False;
382 aStateEvent.State <<= (rtl::OUString(
383 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
384 aTitle );
385 Control->statusChanged(aStateEvent);
389 osl::MutexGuard aGuard(m_aMutex);
390 if(!m_pStatCL)
391 m_pStatCL =
392 new StatusChangeListenerContainer(m_aMutex);
395 m_pStatCL->addInterface(URL.Complete,Control);
396 return;
399 if(URL.Complete == m_aInterceptedURL[5])
400 { // SaveAs
401 frame::FeatureStateEvent aStateEvent;
402 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
403 aStateEvent.FeatureDescriptor = rtl::OUString(
404 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
405 aStateEvent.IsEnabled = sal_True;
406 aStateEvent.Requery = sal_False;
407 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
408 Control->statusChanged(aStateEvent);
411 osl::MutexGuard aGuard(m_aMutex);
412 if(!m_pStatCL)
413 m_pStatCL =
414 new StatusChangeListenerContainer(m_aMutex);
417 m_pStatCL->addInterface(URL.Complete,Control);
418 return;
424 void SAL_CALL
425 Interceptor::removeStatusListener(
426 const uno::Reference<
427 frame::XStatusListener >& Control,
428 const util::URL& URL )
429 throw (
430 uno::RuntimeException
433 if(!(Control.is() && m_pStatCL))
434 return;
435 else {
436 m_pStatCL->removeInterface(URL.Complete,Control);
437 return;
442 //XInterceptorInfo
443 uno::Sequence< ::rtl::OUString >
444 SAL_CALL
445 Interceptor::getInterceptedURLs( )
446 throw (
447 uno::RuntimeException
450 // now implemented as update
451 if ( m_bLink )
453 uno::Sequence< ::rtl::OUString > aResult( 2 );
454 aResult[0] = m_aInterceptedURL[1];
455 aResult[1] = m_aInterceptedURL[5];
457 return aResult;
460 return m_aInterceptedURL;
464 // XDispatchProvider
466 uno::Reference< frame::XDispatch > SAL_CALL
467 Interceptor::queryDispatch(
468 const util::URL& URL,
469 const ::rtl::OUString& TargetFrameName,
470 sal_Int32 SearchFlags )
471 throw (
472 uno::RuntimeException
475 osl::MutexGuard aGuard(m_aMutex);
476 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
477 return (frame::XDispatch*)this;
478 else if(URL.Complete == m_aInterceptedURL[1])
479 return (frame::XDispatch*)0 ;
480 else if( !m_bLink && URL.Complete == m_aInterceptedURL[2] )
481 return (frame::XDispatch*)this;
482 else if( !m_bLink && URL.Complete == m_aInterceptedURL[3] )
483 return (frame::XDispatch*)this;
484 else if( !m_bLink && URL.Complete == m_aInterceptedURL[4] )
485 return (frame::XDispatch*)this;
486 else if(URL.Complete == m_aInterceptedURL[5])
487 return (frame::XDispatch*)this;
488 else {
489 if(m_xSlaveDispatchProvider.is())
490 return m_xSlaveDispatchProvider->queryDispatch(
491 URL,TargetFrameName,SearchFlags);
492 else
493 return uno::Reference<frame::XDispatch>(0);
497 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
498 Interceptor::queryDispatches(
499 const uno::Sequence<frame::DispatchDescriptor >& Requests )
500 throw (
501 uno::RuntimeException
504 uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
505 osl::MutexGuard aGuard(m_aMutex);
506 if(m_xSlaveDispatchProvider.is())
507 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
508 else
509 aRet.realloc(Requests.getLength());
511 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
512 if ( !m_bLink && m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete )
513 aRet[i] = (frame::XDispatch*) this;
514 else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
515 aRet[i] = (frame::XDispatch*) 0;
516 else if( !m_bLink && m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete )
517 aRet[i] = (frame::XDispatch*) this;
518 else if( !m_bLink && m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete )
519 aRet[i] = (frame::XDispatch*) this;
520 else if( !m_bLink && m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete )
521 aRet[i] = (frame::XDispatch*) this;
522 else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
523 aRet[i] = (frame::XDispatch*) this;
525 return aRet;
530 //XDispatchProviderInterceptor
532 uno::Reference< frame::XDispatchProvider > SAL_CALL
533 Interceptor::getSlaveDispatchProvider( )
534 throw (
535 uno::RuntimeException
538 osl::MutexGuard aGuard(m_aMutex);
539 return m_xSlaveDispatchProvider;
542 void SAL_CALL
543 Interceptor::setSlaveDispatchProvider(
544 const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider )
545 throw (
546 uno::RuntimeException
549 osl::MutexGuard aGuard(m_aMutex);
550 m_xSlaveDispatchProvider = NewDispatchProvider;
554 uno::Reference< frame::XDispatchProvider > SAL_CALL
555 Interceptor::getMasterDispatchProvider( )
556 throw (
557 uno::RuntimeException
560 osl::MutexGuard aGuard(m_aMutex);
561 return m_xMasterDispatchProvider;
565 void SAL_CALL
566 Interceptor::setMasterDispatchProvider(
567 const uno::Reference< frame::XDispatchProvider >& NewSupplier )
568 throw (
569 uno::RuntimeException
572 osl::MutexGuard aGuard(m_aMutex);
573 m_xMasterDispatchProvider = NewSupplier;
576 // Fix strange warnings about some
577 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
578 // warning C4505: 'xxx' : unreferenced local function has been removed
579 #if defined(_MSC_VER)
580 #pragma warning(disable: 4505)
581 #endif
583 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */