update credits
[LibreOffice.git] / embedserv / source / embed / intercept.cxx
blobdf1bc83fb959a5ae07b1053da4bd04aa1b21ba78
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< OUString > Interceptor::m_aInterceptedURL(IUL);
38 struct equalOUString
40 bool operator()(
41 const OUString& rKey1,
42 const OUString& rKey2 ) const
44 return !!( rKey1 == rKey2 );
49 struct hashOUString
51 size_t operator()( const OUString& rName ) const
53 return rName.hashCode();
59 class StatusChangeListenerContainer
60 : public ::cppu::OMultiTypeInterfaceContainerHelperVar<
61 OUString,hashOUString,equalOUString>
63 public:
64 StatusChangeListenerContainer( ::osl::Mutex& aMutex )
65 : cppu::OMultiTypeInterfaceContainerHelperVar<
66 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] = OUString(".uno:Save");
131 m_aInterceptedURL[1] = OUString(".uno:SaveAll");
132 m_aInterceptedURL[2] = OUString(".uno:CloseDoc");
133 m_aInterceptedURL[3] = OUString(".uno:CloseWin");
134 m_aInterceptedURL[4] = OUString(".uno:CloseFrame");
135 m_aInterceptedURL[5] = OUString(".uno:SaveAs");
139 Interceptor::~Interceptor()
141 if( m_pDisposeEventListeners )
142 delete m_pDisposeEventListeners;
144 if(m_pStatCL)
145 delete m_pStatCL;
147 DocumentHolder* pTmpDocH = NULL;
148 uno::Reference< uno::XInterface > xLock;
150 osl::MutexGuard aGuard(m_aMutex);
151 xLock = m_xDocHLocker.get();
152 if ( xLock.is() )
153 pTmpDocH = m_pDocH;
156 if ( pTmpDocH )
157 pTmpDocH->ClearInterceptor();
160 void Interceptor::DisconnectDocHolder()
162 osl::MutexGuard aGuard(m_aMutex);
163 m_xDocHLocker.clear();
164 m_pDocH = NULL;
165 m_xOleAccess = NULL;
168 //XDispatch
169 void SAL_CALL
170 Interceptor::dispatch(
171 const util::URL& URL,
172 const uno::Sequence<
173 beans::PropertyValue >& Arguments )
174 throw (uno::RuntimeException)
176 ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > xOleAccess;
178 osl::MutexGuard aGuard(m_aMutex);
179 xOleAccess = m_xOleAccess;
182 if ( xOleAccess.is() )
184 LockedEmbedDocument_Impl aDocLock = xOleAccess->GetEmbedDocument();
185 if ( aDocLock.GetEmbedDocument() )
187 if( !m_bLink && URL.Complete == m_aInterceptedURL[0])
188 aDocLock.GetEmbedDocument()->SaveObject();
189 else if(!m_bLink
190 && ( URL.Complete == m_aInterceptedURL[2] ||
191 URL.Complete == m_aInterceptedURL[3] ||
192 URL.Complete == m_aInterceptedURL[4] ) )
193 aDocLock.GetEmbedDocument()->Close( 0 );
194 else if ( URL.Complete == m_aInterceptedURL[5] )
196 uno::Sequence< beans::PropertyValue > aNewArgs = Arguments;
197 sal_Int32 nInd = 0;
199 while( nInd < aNewArgs.getLength() )
201 if ( aNewArgs[nInd].Name == "SaveTo" )
203 aNewArgs[nInd].Value <<= sal_True;
204 break;
206 nInd++;
209 if ( nInd == aNewArgs.getLength() )
211 aNewArgs.realloc( nInd + 1 );
212 aNewArgs[nInd].Name = OUString( "SaveTo" );
213 aNewArgs[nInd].Value <<= sal_True;
216 uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
217 URL, OUString( "_self" ), 0 );
218 if ( xDispatch.is() )
219 xDispatch->dispatch( URL, aNewArgs );
226 void Interceptor::generateFeatureStateEvent()
228 if( m_pStatCL )
230 DocumentHolder* pTmpDocH = NULL;
231 uno::Reference< uno::XInterface > xLock;
233 osl::MutexGuard aGuard(m_aMutex);
234 xLock = m_xDocHLocker.get();
235 if ( xLock.is() )
236 pTmpDocH = m_pDocH;
239 OUString aTitle;
240 if ( pTmpDocH )
241 aTitle = pTmpDocH->getTitle();
243 for(int i = 0; i < IUL; ++i)
245 if( i == 1 || m_bLink && i != 5 )
246 continue;
248 cppu::OInterfaceContainerHelper* pICH =
249 m_pStatCL->getContainer(m_aInterceptedURL[i]);
250 uno::Sequence<uno::Reference<uno::XInterface> > aSeq;
251 if(pICH)
252 aSeq = pICH->getElements();
253 if(!aSeq.getLength())
254 continue;
256 frame::FeatureStateEvent aStateEvent;
257 aStateEvent.IsEnabled = sal_True;
258 aStateEvent.Requery = sal_False;
259 if(i == 0)
262 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
263 aStateEvent.FeatureDescriptor = OUString("Update");
264 aStateEvent.State <<= (OUString(
265 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
266 aTitle);
269 else if ( i == 5 )
271 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
272 aStateEvent.FeatureDescriptor = OUString("SaveCopyTo");
273 aStateEvent.State <<= (OUString(
274 RTL_CONSTASCII_USTRINGPARAM("($3)")));
276 else
278 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
279 aStateEvent.FeatureDescriptor = OUString("Close and Return");
280 aStateEvent.State <<= (OUString(
281 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
282 aTitle);
286 for(sal_Int32 k = 0; k < aSeq.getLength(); ++k)
288 uno::Reference<frame::XStatusListener>
289 Control(aSeq[k],uno::UNO_QUERY);
290 if(Control.is())
291 Control->statusChanged(aStateEvent);
299 void SAL_CALL
300 Interceptor::addStatusListener(
301 const uno::Reference<
302 frame::XStatusListener >& Control,
303 const util::URL& URL )
304 throw (
305 uno::RuntimeException
308 if(!Control.is())
309 return;
311 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
312 { // Save
313 DocumentHolder* pTmpDocH = NULL;
314 uno::Reference< uno::XInterface > xLock;
316 osl::MutexGuard aGuard(m_aMutex);
317 xLock = m_xDocHLocker.get();
318 if ( xLock.is() )
319 pTmpDocH = m_pDocH;
322 OUString aTitle;
323 if ( pTmpDocH )
324 aTitle = pTmpDocH->getTitle();
326 frame::FeatureStateEvent aStateEvent;
327 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
328 aStateEvent.FeatureDescriptor = OUString("Update");
329 aStateEvent.IsEnabled = sal_True;
330 aStateEvent.Requery = sal_False;
331 aStateEvent.State <<= (OUString(
332 RTL_CONSTASCII_USTRINGPARAM("($1) ")) +
333 aTitle );
334 Control->statusChanged(aStateEvent);
337 osl::MutexGuard aGuard(m_aMutex);
338 if(!m_pStatCL)
339 m_pStatCL =
340 new StatusChangeListenerContainer(m_aMutex);
343 m_pStatCL->addInterface(URL.Complete,Control);
344 return;
347 sal_Int32 i = 2;
348 if ( !m_bLink
349 && ( URL.Complete == m_aInterceptedURL[i] ||
350 URL.Complete == m_aInterceptedURL[++i] ||
351 URL.Complete == m_aInterceptedURL[++i] ) )
352 { // Close and return
353 DocumentHolder* pTmpDocH = NULL;
354 uno::Reference< uno::XInterface > xLock;
356 osl::MutexGuard aGuard(m_aMutex);
357 xLock = m_xDocHLocker.get();
358 if ( xLock.is() )
359 pTmpDocH = m_pDocH;
362 OUString aTitle;
363 if ( pTmpDocH )
364 aTitle = pTmpDocH->getTitle();
366 frame::FeatureStateEvent aStateEvent;
367 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
368 aStateEvent.FeatureDescriptor = OUString("Close and Return");
369 aStateEvent.IsEnabled = sal_True;
370 aStateEvent.Requery = sal_False;
371 aStateEvent.State <<= (OUString(
372 RTL_CONSTASCII_USTRINGPARAM("($2) ")) +
373 aTitle );
374 Control->statusChanged(aStateEvent);
378 osl::MutexGuard aGuard(m_aMutex);
379 if(!m_pStatCL)
380 m_pStatCL =
381 new StatusChangeListenerContainer(m_aMutex);
384 m_pStatCL->addInterface(URL.Complete,Control);
385 return;
388 if(URL.Complete == m_aInterceptedURL[5])
389 { // SaveAs
390 frame::FeatureStateEvent aStateEvent;
391 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
392 aStateEvent.FeatureDescriptor = OUString("SaveCopyTo");
393 aStateEvent.IsEnabled = sal_True;
394 aStateEvent.Requery = sal_False;
395 aStateEvent.State <<= (OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
396 Control->statusChanged(aStateEvent);
399 osl::MutexGuard aGuard(m_aMutex);
400 if(!m_pStatCL)
401 m_pStatCL =
402 new StatusChangeListenerContainer(m_aMutex);
405 m_pStatCL->addInterface(URL.Complete,Control);
406 return;
412 void SAL_CALL
413 Interceptor::removeStatusListener(
414 const uno::Reference<
415 frame::XStatusListener >& Control,
416 const util::URL& URL )
417 throw (
418 uno::RuntimeException
421 if(!(Control.is() && m_pStatCL))
422 return;
423 else {
424 m_pStatCL->removeInterface(URL.Complete,Control);
425 return;
430 //XInterceptorInfo
431 uno::Sequence< OUString >
432 SAL_CALL
433 Interceptor::getInterceptedURLs( )
434 throw (
435 uno::RuntimeException
438 // now implemented as update
439 if ( m_bLink )
441 uno::Sequence< OUString > aResult( 2 );
442 aResult[0] = m_aInterceptedURL[1];
443 aResult[1] = m_aInterceptedURL[5];
445 return aResult;
448 return m_aInterceptedURL;
452 // XDispatchProvider
454 uno::Reference< frame::XDispatch > SAL_CALL
455 Interceptor::queryDispatch(
456 const util::URL& URL,
457 const OUString& TargetFrameName,
458 sal_Int32 SearchFlags )
459 throw (
460 uno::RuntimeException
463 osl::MutexGuard aGuard(m_aMutex);
464 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
465 return (frame::XDispatch*)this;
466 else if(URL.Complete == m_aInterceptedURL[1])
467 return (frame::XDispatch*)0 ;
468 else if( !m_bLink && URL.Complete == m_aInterceptedURL[2] )
469 return (frame::XDispatch*)this;
470 else if( !m_bLink && URL.Complete == m_aInterceptedURL[3] )
471 return (frame::XDispatch*)this;
472 else if( !m_bLink && URL.Complete == m_aInterceptedURL[4] )
473 return (frame::XDispatch*)this;
474 else if(URL.Complete == m_aInterceptedURL[5])
475 return (frame::XDispatch*)this;
476 else {
477 if(m_xSlaveDispatchProvider.is())
478 return m_xSlaveDispatchProvider->queryDispatch(
479 URL,TargetFrameName,SearchFlags);
480 else
481 return uno::Reference<frame::XDispatch>(0);
485 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
486 Interceptor::queryDispatches(
487 const uno::Sequence<frame::DispatchDescriptor >& Requests )
488 throw (
489 uno::RuntimeException
492 uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
493 osl::MutexGuard aGuard(m_aMutex);
494 if(m_xSlaveDispatchProvider.is())
495 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
496 else
497 aRet.realloc(Requests.getLength());
499 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
500 if ( !m_bLink && m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete )
501 aRet[i] = (frame::XDispatch*) this;
502 else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
503 aRet[i] = (frame::XDispatch*) 0;
504 else if( !m_bLink && m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete )
505 aRet[i] = (frame::XDispatch*) this;
506 else if( !m_bLink && m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete )
507 aRet[i] = (frame::XDispatch*) this;
508 else if( !m_bLink && m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete )
509 aRet[i] = (frame::XDispatch*) this;
510 else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
511 aRet[i] = (frame::XDispatch*) this;
513 return aRet;
518 //XDispatchProviderInterceptor
520 uno::Reference< frame::XDispatchProvider > SAL_CALL
521 Interceptor::getSlaveDispatchProvider( )
522 throw (
523 uno::RuntimeException
526 osl::MutexGuard aGuard(m_aMutex);
527 return m_xSlaveDispatchProvider;
530 void SAL_CALL
531 Interceptor::setSlaveDispatchProvider(
532 const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider )
533 throw (
534 uno::RuntimeException
537 osl::MutexGuard aGuard(m_aMutex);
538 m_xSlaveDispatchProvider = NewDispatchProvider;
542 uno::Reference< frame::XDispatchProvider > SAL_CALL
543 Interceptor::getMasterDispatchProvider( )
544 throw (
545 uno::RuntimeException
548 osl::MutexGuard aGuard(m_aMutex);
549 return m_xMasterDispatchProvider;
553 void SAL_CALL
554 Interceptor::setMasterDispatchProvider(
555 const uno::Reference< frame::XDispatchProvider >& NewSupplier )
556 throw (
557 uno::RuntimeException
560 osl::MutexGuard aGuard(m_aMutex);
561 m_xMasterDispatchProvider = NewSupplier;
564 // Fix strange warnings about some
565 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
566 // warning C4505: 'xxx' : unreferenced local function has been removed
567 #if defined(_MSC_VER)
568 #pragma warning(disable: 4505)
569 #endif
571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */