GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / uno / statusbarcontroller.cxx
blobd7c700aeb4f0144daec8817309993d72e823febe
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 .
20 #include <svtools/statusbarcontroller.hxx>
21 #include <com/sun/star/beans/PropertyValue.hpp>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/frame/XDispatchProvider.hpp>
24 #include <com/sun/star/lang/DisposedException.hpp>
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 #include <com/sun/star/frame/XLayoutManager.hpp>
27 #include <com/sun/star/util/URLTransformer.hpp>
28 #include <osl/mutex.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/status.hxx>
32 #include <svtools/imgdef.hxx>
33 #include <svtools/miscopt.hxx>
34 #include <toolkit/helper/vclunohelper.hxx>
35 #include <comphelper/processfactory.hxx>
37 using namespace ::cppu;
38 using namespace ::com::sun::star::awt;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::util;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::lang;
43 using namespace ::com::sun::star::frame;
45 namespace svt
48 StatusbarController::StatusbarController(
49 const Reference< XComponentContext >& rxContext,
50 const Reference< XFrame >& xFrame,
51 const OUString& aCommandURL,
52 unsigned short nID ) :
53 OWeakObject()
54 , m_bInitialized( sal_False )
55 , m_bDisposed( sal_False )
56 , m_nID( nID )
57 , m_xFrame( xFrame )
58 , m_xContext( rxContext )
59 , m_aCommandURL( aCommandURL )
60 , m_aListenerContainer( m_aMutex )
64 StatusbarController::StatusbarController() :
65 OWeakObject()
66 , m_bInitialized( sal_False )
67 , m_bDisposed( sal_False )
68 , m_nID( 0 )
69 , m_aListenerContainer( m_aMutex )
73 StatusbarController::~StatusbarController()
77 Reference< XFrame > StatusbarController::getFrameInterface() const
79 SolarMutexGuard aSolarMutexGuard;
80 return m_xFrame;
83 Reference< XURLTransformer > StatusbarController::getURLTransformer() const
85 SolarMutexGuard aSolarMutexGuard;
86 if ( !m_xURLTransformer.is() && m_xContext.is() )
88 m_xURLTransformer = com::sun::star::util::URLTransformer::create( m_xContext );
91 return m_xURLTransformer;
94 // XInterface
95 Any SAL_CALL StatusbarController::queryInterface( const Type& rType )
96 throw ( RuntimeException )
98 Any a = ::cppu::queryInterface(
99 rType ,
100 static_cast< XStatusbarController* >( this ),
101 static_cast< XStatusListener* >( this ),
102 static_cast< XEventListener* >( this ),
103 static_cast< XInitialization* >( this ),
104 static_cast< XComponent* >( this ),
105 static_cast< XUpdatable* >( this ));
107 if ( a.hasValue() )
108 return a;
110 return OWeakObject::queryInterface( rType );
113 void SAL_CALL StatusbarController::acquire() throw ()
115 OWeakObject::acquire();
118 void SAL_CALL StatusbarController::release() throw ()
120 OWeakObject::release();
123 void SAL_CALL StatusbarController::initialize( const Sequence< Any >& aArguments )
124 throw ( Exception, RuntimeException )
126 bool bInitialized( true );
129 SolarMutexGuard aSolarMutexGuard;
131 if ( m_bDisposed )
132 throw DisposedException();
134 bInitialized = m_bInitialized;
137 if ( !bInitialized )
139 SolarMutexGuard aSolarMutexGuard;
140 m_bInitialized = sal_True;
142 PropertyValue aPropValue;
143 for ( int i = 0; i < aArguments.getLength(); i++ )
145 if ( aArguments[i] >>= aPropValue )
147 if ( aPropValue.Name == "Frame" )
148 aPropValue.Value >>= m_xFrame;
149 else if ( aPropValue.Name == "CommandURL" )
150 aPropValue.Value >>= m_aCommandURL;
151 else if ( aPropValue.Name == "ServiceManager" )
153 Reference<XMultiServiceFactory> xMSF;
154 aPropValue.Value >>= xMSF;
155 if( xMSF.is() )
156 m_xContext = comphelper::getComponentContext(xMSF);
158 else if ( aPropValue.Name == "ParentWindow" )
159 aPropValue.Value >>= m_xParentWindow;
160 else if ( aPropValue.Name == "Identifier" )
161 aPropValue.Value >>= m_nID;
162 else if ( aPropValue.Name == "StatusbarItem" )
163 aPropValue.Value >>= m_xStatusbarItem;
167 if ( !m_aCommandURL.isEmpty() )
168 m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() ));
172 void SAL_CALL StatusbarController::update()
173 throw ( RuntimeException )
176 SolarMutexGuard aSolarMutexGuard;
177 if ( m_bDisposed )
178 throw DisposedException();
181 // Bind all registered listeners to their dispatch objects
182 bindListener();
185 // XComponent
186 void SAL_CALL StatusbarController::dispose()
187 throw (::com::sun::star::uno::RuntimeException)
189 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
192 SolarMutexGuard aSolarMutexGuard;
193 if ( m_bDisposed )
194 throw DisposedException();
197 com::sun::star::lang::EventObject aEvent( xThis );
198 m_aListenerContainer.disposeAndClear( aEvent );
200 SolarMutexGuard aSolarMutexGuard;
201 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
202 Reference< XURLTransformer > xURLTransformer = getURLTransformer();
203 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
204 com::sun::star::util::URL aTargetURL;
205 while ( pIter != m_aListenerMap.end() )
209 Reference< XDispatch > xDispatch( pIter->second );
210 aTargetURL.Complete = pIter->first;
211 xURLTransformer->parseStrict( aTargetURL );
213 if ( xDispatch.is() && xStatusListener.is() )
214 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
216 catch ( Exception& )
220 ++pIter;
223 // clear hash map
224 m_aListenerMap.clear();
226 // release references
227 m_xURLTransformer.clear();
228 m_xContext.clear();
229 m_xFrame.clear();
230 m_xParentWindow.clear();
231 m_xStatusbarItem.clear();
233 m_bDisposed = sal_True;
236 void SAL_CALL StatusbarController::addEventListener( const Reference< XEventListener >& xListener )
237 throw ( RuntimeException )
239 m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
242 void SAL_CALL StatusbarController::removeEventListener( const Reference< XEventListener >& aListener )
243 throw ( RuntimeException )
245 m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener );
248 // XEventListener
249 void SAL_CALL StatusbarController::disposing( const EventObject& Source )
250 throw ( RuntimeException )
252 SolarMutexGuard aSolarMutexGuard;
254 if ( m_bDisposed )
255 return;
257 Reference< XFrame > xFrame( Source.Source, UNO_QUERY );
258 if ( xFrame.is() )
260 if ( xFrame == m_xFrame )
261 m_xFrame.clear();
262 return;
265 Reference< XDispatch > xDispatch( Source.Source, UNO_QUERY );
266 if ( !xDispatch.is() )
267 return;
269 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
270 while ( pIter != m_aListenerMap.end() )
272 // Compare references and release dispatch references if they are equal.
273 if ( xDispatch == pIter->second )
274 pIter->second.clear();
275 ++pIter;
279 // XStatusListener
280 void SAL_CALL StatusbarController::statusChanged( const FeatureStateEvent& Event )
281 throw ( RuntimeException )
283 SolarMutexGuard aSolarMutexGuard;
285 if ( m_bDisposed )
286 return;
288 Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
289 if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR && m_nID != 0 )
291 OUString aStrValue;
292 StatusBar* pStatusBar = (StatusBar *)pWindow;
294 if ( Event.State >>= aStrValue )
295 pStatusBar->SetItemText( m_nID, aStrValue );
296 else if ( !Event.State.hasValue() )
297 pStatusBar->SetItemText( m_nID, "" );
301 // XStatusbarController
302 ::sal_Bool SAL_CALL StatusbarController::mouseButtonDown(
303 const ::com::sun::star::awt::MouseEvent& )
304 throw (::com::sun::star::uno::RuntimeException)
306 return sal_False;
309 ::sal_Bool SAL_CALL StatusbarController::mouseMove(
310 const ::com::sun::star::awt::MouseEvent& )
311 throw (::com::sun::star::uno::RuntimeException)
313 return sal_False;
316 ::sal_Bool SAL_CALL StatusbarController::mouseButtonUp(
317 const ::com::sun::star::awt::MouseEvent& )
318 throw (::com::sun::star::uno::RuntimeException)
320 return sal_False;
323 void SAL_CALL StatusbarController::command(
324 const ::com::sun::star::awt::Point&,
325 ::sal_Int32,
326 ::sal_Bool,
327 const ::com::sun::star::uno::Any& )
328 throw (::com::sun::star::uno::RuntimeException)
332 void SAL_CALL StatusbarController::paint(
333 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >&,
334 const ::com::sun::star::awt::Rectangle&,
335 ::sal_Int32 )
336 throw (::com::sun::star::uno::RuntimeException)
340 void SAL_CALL StatusbarController::click( const ::com::sun::star::awt::Point& )
341 throw (::com::sun::star::uno::RuntimeException)
345 void SAL_CALL StatusbarController::doubleClick( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException)
347 SolarMutexGuard aSolarMutexGuard;
349 if ( m_bDisposed )
350 return;
352 Sequence< PropertyValue > aArgs;
353 execute( aArgs );
356 void StatusbarController::addStatusListener( const OUString& aCommandURL )
358 Reference< XDispatch > xDispatch;
359 Reference< XStatusListener > xStatusListener;
360 com::sun::star::util::URL aTargetURL;
363 SolarMutexGuard aSolarMutexGuard;
364 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
366 // Already in the list of status listener. Do nothing.
367 if ( pIter != m_aListenerMap.end() )
368 return;
370 // Check if we are already initialized. Implementation starts adding itself as status listener when
371 // intialize is called.
372 if ( !m_bInitialized )
374 // Put into the boost::unordered_map of status listener. Will be activated when initialized is called
375 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
376 return;
378 else
380 // Add status listener directly as intialize has already been called.
381 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
382 if ( m_xContext.is() && xDispatchProvider.is() )
384 Reference< XURLTransformer > xURLTransformer = getURLTransformer();
385 aTargetURL.Complete = aCommandURL;
386 xURLTransformer->parseStrict( aTargetURL );
387 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
389 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
390 URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
391 if ( aIter != m_aListenerMap.end() )
393 Reference< XDispatch > xOldDispatch( aIter->second );
394 aIter->second = xDispatch;
398 if ( xOldDispatch.is() )
399 xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
401 catch ( Exception& )
405 else
406 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
411 // Call without locked mutex as we are called back from dispatch implementation
414 if ( xDispatch.is() )
415 xDispatch->addStatusListener( xStatusListener, aTargetURL );
417 catch ( Exception& )
422 void StatusbarController::bindListener()
424 std::vector< Listener > aDispatchVector;
425 Reference< XStatusListener > xStatusListener;
428 SolarMutexGuard aSolarMutexGuard;
430 if ( !m_bInitialized )
431 return;
433 // Collect all registered command URL's and store them temporary
434 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
435 if ( m_xContext.is() && xDispatchProvider.is() )
437 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
438 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
439 while ( pIter != m_aListenerMap.end() )
441 Reference< XURLTransformer > xURLTransformer = getURLTransformer();
442 com::sun::star::util::URL aTargetURL;
443 aTargetURL.Complete = pIter->first;
444 xURLTransformer->parseStrict( aTargetURL );
446 Reference< XDispatch > xDispatch( pIter->second );
447 if ( xDispatch.is() )
449 // We already have a dispatch object => we have to requery.
450 // Release old dispatch object and remove it as listener
453 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
455 catch ( Exception& )
460 pIter->second.clear();
461 xDispatch.clear();
463 // Query for dispatch object. Old dispatch will be released with this, too.
466 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
468 catch ( Exception& )
471 pIter->second = xDispatch;
473 Listener aListener( aTargetURL, xDispatch );
474 aDispatchVector.push_back( aListener );
475 ++pIter;
480 // Call without locked mutex as we are called back from dispatch implementation
481 if ( !xStatusListener.is() )
482 return;
484 for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
488 Listener& rListener = aDispatchVector[i];
489 if ( rListener.xDispatch.is() )
490 rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
491 else if ( rListener.aURL.Complete == m_aCommandURL )
493 // Send status changed for the main URL, if we cannot get a valid dispatch object.
494 // UI disables the button. Catch exception as we release our mutex, it is possible
495 // that someone else already disposed this instance!
496 FeatureStateEvent aFeatureStateEvent;
497 aFeatureStateEvent.IsEnabled = sal_False;
498 aFeatureStateEvent.FeatureURL = rListener.aURL;
499 aFeatureStateEvent.State = Any();
500 xStatusListener->statusChanged( aFeatureStateEvent );
503 catch ( ... ){}
507 ::Rectangle StatusbarController::getControlRect() const
509 ::Rectangle aRect;
512 SolarMutexGuard aSolarMutexGuard;
514 if ( m_bDisposed )
515 throw DisposedException();
517 if ( m_xParentWindow.is() )
519 StatusBar* pStatusBar = dynamic_cast< StatusBar* >( VCLUnoHelper::GetWindow( m_xParentWindow ));
520 if ( pStatusBar && pStatusBar->GetType() == WINDOW_STATUSBAR )
521 aRect = pStatusBar->GetItemRect( m_nID );
525 return aRect;
528 void StatusbarController::execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs )
530 Reference< XDispatch > xDispatch;
531 Reference< XURLTransformer > xURLTransformer;
532 OUString aCommandURL;
535 SolarMutexGuard aSolarMutexGuard;
537 if ( m_bDisposed )
538 throw DisposedException();
540 if ( m_bInitialized &&
541 m_xFrame.is() &&
542 m_xContext.is() &&
543 !m_aCommandURL.isEmpty() )
545 xURLTransformer = getURLTransformer();
546 aCommandURL = m_aCommandURL;
547 URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
548 if ( pIter != m_aListenerMap.end() )
549 xDispatch = pIter->second;
553 if ( xDispatch.is() && xURLTransformer.is() )
557 com::sun::star::util::URL aTargetURL;
559 aTargetURL.Complete = aCommandURL;
560 xURLTransformer->parseStrict( aTargetURL );
561 xDispatch->dispatch( aTargetURL, aArgs );
563 catch ( DisposedException& )
569 void StatusbarController::execute(
570 const OUString& aCommandURL,
571 const Sequence< ::com::sun::star::beans::PropertyValue >& aArgs )
573 Reference< XDispatch > xDispatch;
574 com::sun::star::util::URL aTargetURL;
577 SolarMutexGuard aSolarMutexGuard;
579 if ( m_bDisposed )
580 throw DisposedException();
582 if ( m_bInitialized &&
583 m_xFrame.is() &&
584 m_xContext.is() &&
585 !m_aCommandURL.isEmpty() )
587 Reference< XURLTransformer > xURLTransformer( getURLTransformer() );
588 aTargetURL.Complete = aCommandURL;
589 xURLTransformer->parseStrict( aTargetURL );
591 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
592 if ( pIter != m_aListenerMap.end() )
593 xDispatch = pIter->second;
594 else
596 Reference< ::com::sun::star::frame::XDispatchProvider > xDispatchProvider(
597 m_xFrame->getController(), UNO_QUERY );
598 if ( xDispatchProvider.is() )
599 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
604 if ( xDispatch.is() )
608 xDispatch->dispatch( aTargetURL, aArgs );
610 catch ( DisposedException& )
616 } // svt
618 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */