Stop leaking all ScPostIt instances.
[LibreOffice.git] / embedserv / source / embed / intercept.cxx
blobeba61b4b55d19368bc55d90df9461704a7553a42
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] = ".uno:Save";
131 m_aInterceptedURL[1] = ".uno:SaveAll";
132 m_aInterceptedURL[2] = ".uno:CloseDoc";
133 m_aInterceptedURL[3] = ".uno:CloseWin";
134 m_aInterceptedURL[4] = ".uno:CloseFrame";
135 m_aInterceptedURL[5] = ".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 = "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 = "Update";
264 aStateEvent.State <<= (OUString("($1) ") + aTitle);
267 else if ( i == 5 )
269 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
270 aStateEvent.FeatureDescriptor = "SaveCopyTo";
271 aStateEvent.State <<= (OUString("($3)"));
273 else
275 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
276 aStateEvent.FeatureDescriptor = "Close and Return";
277 aStateEvent.State <<= (OUString("($2) ") + aTitle);
281 for(sal_Int32 k = 0; k < aSeq.getLength(); ++k)
283 uno::Reference<frame::XStatusListener>
284 Control(aSeq[k],uno::UNO_QUERY);
285 if(Control.is())
286 Control->statusChanged(aStateEvent);
294 void SAL_CALL
295 Interceptor::addStatusListener(
296 const uno::Reference<
297 frame::XStatusListener >& Control,
298 const util::URL& URL )
299 throw (
300 uno::RuntimeException
303 if(!Control.is())
304 return;
306 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
307 { // Save
308 DocumentHolder* pTmpDocH = NULL;
309 uno::Reference< uno::XInterface > xLock;
311 osl::MutexGuard aGuard(m_aMutex);
312 xLock = m_xDocHLocker.get();
313 if ( xLock.is() )
314 pTmpDocH = m_pDocH;
317 OUString aTitle;
318 if ( pTmpDocH )
319 aTitle = pTmpDocH->getTitle();
321 frame::FeatureStateEvent aStateEvent;
322 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0];
323 aStateEvent.FeatureDescriptor = "Update";
324 aStateEvent.IsEnabled = sal_True;
325 aStateEvent.Requery = sal_False;
326 aStateEvent.State <<= (OUString("($1) ") + aTitle );
327 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 sal_Int32 i = 2;
341 if ( !m_bLink
342 && ( URL.Complete == m_aInterceptedURL[i] ||
343 URL.Complete == m_aInterceptedURL[++i] ||
344 URL.Complete == m_aInterceptedURL[++i] ) )
345 { // Close and return
346 DocumentHolder* pTmpDocH = NULL;
347 uno::Reference< uno::XInterface > xLock;
349 osl::MutexGuard aGuard(m_aMutex);
350 xLock = m_xDocHLocker.get();
351 if ( xLock.is() )
352 pTmpDocH = m_pDocH;
355 OUString aTitle;
356 if ( pTmpDocH )
357 aTitle = pTmpDocH->getTitle();
359 frame::FeatureStateEvent aStateEvent;
360 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
361 aStateEvent.FeatureDescriptor = "Close and Return";
362 aStateEvent.IsEnabled = sal_True;
363 aStateEvent.Requery = sal_False;
364 aStateEvent.State <<= (OUString("($2) ") + aTitle );
365 Control->statusChanged(aStateEvent);
369 osl::MutexGuard aGuard(m_aMutex);
370 if(!m_pStatCL)
371 m_pStatCL =
372 new StatusChangeListenerContainer(m_aMutex);
375 m_pStatCL->addInterface(URL.Complete,Control);
376 return;
379 if(URL.Complete == m_aInterceptedURL[5])
380 { // SaveAs
381 frame::FeatureStateEvent aStateEvent;
382 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5];
383 aStateEvent.FeatureDescriptor = "SaveCopyTo";
384 aStateEvent.IsEnabled = sal_True;
385 aStateEvent.Requery = sal_False;
386 aStateEvent.State <<= (OUString("($3)"));
387 Control->statusChanged(aStateEvent);
390 osl::MutexGuard aGuard(m_aMutex);
391 if(!m_pStatCL)
392 m_pStatCL =
393 new StatusChangeListenerContainer(m_aMutex);
396 m_pStatCL->addInterface(URL.Complete,Control);
397 return;
403 void SAL_CALL
404 Interceptor::removeStatusListener(
405 const uno::Reference<
406 frame::XStatusListener >& Control,
407 const util::URL& URL )
408 throw (
409 uno::RuntimeException
412 if(!(Control.is() && m_pStatCL))
413 return;
414 else {
415 m_pStatCL->removeInterface(URL.Complete,Control);
416 return;
421 //XInterceptorInfo
422 uno::Sequence< OUString >
423 SAL_CALL
424 Interceptor::getInterceptedURLs( )
425 throw (
426 uno::RuntimeException
429 // now implemented as update
430 if ( m_bLink )
432 uno::Sequence< OUString > aResult( 2 );
433 aResult[0] = m_aInterceptedURL[1];
434 aResult[1] = m_aInterceptedURL[5];
436 return aResult;
439 return m_aInterceptedURL;
443 // XDispatchProvider
445 uno::Reference< frame::XDispatch > SAL_CALL
446 Interceptor::queryDispatch(
447 const util::URL& URL,
448 const OUString& TargetFrameName,
449 sal_Int32 SearchFlags )
450 throw (
451 uno::RuntimeException
454 osl::MutexGuard aGuard(m_aMutex);
455 if( !m_bLink && URL.Complete == m_aInterceptedURL[0] )
456 return (frame::XDispatch*)this;
457 else if(URL.Complete == m_aInterceptedURL[1])
458 return (frame::XDispatch*)0 ;
459 else if( !m_bLink && URL.Complete == m_aInterceptedURL[2] )
460 return (frame::XDispatch*)this;
461 else if( !m_bLink && URL.Complete == m_aInterceptedURL[3] )
462 return (frame::XDispatch*)this;
463 else if( !m_bLink && URL.Complete == m_aInterceptedURL[4] )
464 return (frame::XDispatch*)this;
465 else if(URL.Complete == m_aInterceptedURL[5])
466 return (frame::XDispatch*)this;
467 else {
468 if(m_xSlaveDispatchProvider.is())
469 return m_xSlaveDispatchProvider->queryDispatch(
470 URL,TargetFrameName,SearchFlags);
471 else
472 return uno::Reference<frame::XDispatch>(0);
476 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
477 Interceptor::queryDispatches(
478 const uno::Sequence<frame::DispatchDescriptor >& Requests )
479 throw (
480 uno::RuntimeException
483 uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
484 osl::MutexGuard aGuard(m_aMutex);
485 if(m_xSlaveDispatchProvider.is())
486 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
487 else
488 aRet.realloc(Requests.getLength());
490 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
491 if ( !m_bLink && m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete )
492 aRet[i] = (frame::XDispatch*) this;
493 else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
494 aRet[i] = (frame::XDispatch*) 0;
495 else if( !m_bLink && m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete )
496 aRet[i] = (frame::XDispatch*) this;
497 else if( !m_bLink && m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete )
498 aRet[i] = (frame::XDispatch*) this;
499 else if( !m_bLink && m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete )
500 aRet[i] = (frame::XDispatch*) this;
501 else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
502 aRet[i] = (frame::XDispatch*) this;
504 return aRet;
509 //XDispatchProviderInterceptor
511 uno::Reference< frame::XDispatchProvider > SAL_CALL
512 Interceptor::getSlaveDispatchProvider( )
513 throw (
514 uno::RuntimeException
517 osl::MutexGuard aGuard(m_aMutex);
518 return m_xSlaveDispatchProvider;
521 void SAL_CALL
522 Interceptor::setSlaveDispatchProvider(
523 const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider )
524 throw (
525 uno::RuntimeException
528 osl::MutexGuard aGuard(m_aMutex);
529 m_xSlaveDispatchProvider = NewDispatchProvider;
533 uno::Reference< frame::XDispatchProvider > SAL_CALL
534 Interceptor::getMasterDispatchProvider( )
535 throw (
536 uno::RuntimeException
539 osl::MutexGuard aGuard(m_aMutex);
540 return m_xMasterDispatchProvider;
544 void SAL_CALL
545 Interceptor::setMasterDispatchProvider(
546 const uno::Reference< frame::XDispatchProvider >& NewSupplier )
547 throw (
548 uno::RuntimeException
551 osl::MutexGuard aGuard(m_aMutex);
552 m_xMasterDispatchProvider = NewSupplier;
555 // Fix strange warnings about some
556 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
557 // warning C4505: 'xxx' : unreferenced local function has been removed
558 #if defined(_MSC_VER)
559 #pragma warning(disable: 4505)
560 #endif
562 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */