merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / uno / toolboxcontroller.cxx
blob8ab4ab55a0948a7e9fa3142c66642aac52814b74
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: toolboxcontroller.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <svtools/toolboxcontroller.hxx>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/frame/XDispatchProvider.hpp>
37 #include <com/sun/star/lang/DisposedException.hpp>
38 #include <com/sun/star/frame/XLayoutManager.hpp>
39 #include <vos/mutex.hxx>
40 #include <vcl/svapp.hxx>
41 #include <imgdef.hxx>
42 #include <svtools/miscopt.hxx>
44 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
45 #include <toolkit/unohlp.hxx>
46 #endif
47 #include <vcl/toolbox.hxx>
49 using namespace ::cppu;
50 using namespace ::com::sun::star::awt;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::util;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::frame;
56 using namespace ::com::sun::star::frame;
58 namespace svt
60 struct ToolboxController_Impl
62 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParentWindow;
63 ::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xUrlTransformer;
66 ToolboxController::ToolboxController(
67 const Reference< XMultiServiceFactory >& rServiceManager,
68 const Reference< XFrame >& xFrame,
69 const ::rtl::OUString& aCommandURL ) :
70 OWeakObject()
71 , m_bInitialized( sal_False )
72 , m_bDisposed( sal_False )
73 , m_xFrame(xFrame)
74 , m_xServiceManager( rServiceManager )
75 , m_aCommandURL( aCommandURL )
76 , m_aListenerContainer( m_aMutex )
78 m_pImpl = new ToolboxController_Impl;
80 try
82 m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance(
83 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
84 UNO_QUERY );
86 catch(const Exception&)
91 ToolboxController::ToolboxController() :
92 OWeakObject()
93 , m_bInitialized( sal_False )
94 , m_bDisposed( sal_False )
95 , m_aListenerContainer( m_aMutex )
97 m_pImpl = new ToolboxController_Impl;
100 ToolboxController::~ToolboxController()
102 delete m_pImpl;
105 Reference< XFrame > ToolboxController::getFrameInterface() const
107 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
108 return m_xFrame;
111 Reference< XMultiServiceFactory > ToolboxController::getServiceManager() const
113 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
114 return m_xServiceManager;
117 Reference< XLayoutManager > ToolboxController::getLayoutManager() const
119 Reference< XLayoutManager > xLayoutManager;
120 Reference< XPropertySet > xPropSet;
122 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
123 xPropSet = Reference< XPropertySet >( m_xFrame, UNO_QUERY );
126 if ( xPropSet.is() )
130 xLayoutManager.set(xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY);
132 catch ( Exception& )
137 return xLayoutManager;
140 // XInterface
141 Any SAL_CALL ToolboxController::queryInterface( const Type& rType )
142 throw ( RuntimeException )
144 Any a = ::cppu::queryInterface(
145 rType ,
146 static_cast< XToolbarController* >( this ),
147 static_cast< XStatusListener* >( this ),
148 static_cast< XEventListener* >( this ),
149 static_cast< XInitialization* >( this ),
150 static_cast< XComponent* >( this ),
151 static_cast< XUpdatable* >( this ));
153 if ( a.hasValue() )
154 return a;
156 return OWeakObject::queryInterface( rType );
159 void SAL_CALL ToolboxController::acquire() throw ()
161 OWeakObject::acquire();
164 void SAL_CALL ToolboxController::release() throw ()
166 OWeakObject::release();
169 void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments )
170 throw ( Exception, RuntimeException )
172 const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
173 const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
174 const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
175 const rtl::OUString aParentWindow( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
177 bool bInitialized( true );
180 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
182 if ( m_bDisposed )
183 throw DisposedException();
185 bInitialized = m_bInitialized;
188 if ( !bInitialized )
190 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
191 m_bInitialized = sal_True;
193 PropertyValue aPropValue;
194 for ( int i = 0; i < aArguments.getLength(); i++ )
196 if ( aArguments[i] >>= aPropValue )
198 if ( aPropValue.Name.equalsAscii( "Frame" ))
199 m_xFrame.set(aPropValue.Value,UNO_QUERY);
200 else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
201 aPropValue.Value >>= m_aCommandURL;
202 else if ( aPropValue.Name.equalsAscii( "ServiceManager" ))
203 m_xServiceManager.set(aPropValue.Value,UNO_QUERY);
204 else if ( aPropValue.Name.equalsAscii( "ParentWindow" ))
205 m_pImpl->m_xParentWindow.set(aPropValue.Value,UNO_QUERY);
211 if ( !m_pImpl->m_xUrlTransformer.is() && m_xServiceManager.is() )
212 m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance(
213 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
214 UNO_QUERY );
216 catch(const Exception&)
220 if ( m_aCommandURL.getLength() )
221 m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() ));
225 void SAL_CALL ToolboxController::update()
226 throw ( RuntimeException )
229 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
230 if ( m_bDisposed )
231 throw DisposedException();
234 // Bind all registered listeners to their dispatch objects
235 bindListener();
238 // XComponent
239 void SAL_CALL ToolboxController::dispose()
240 throw (::com::sun::star::uno::RuntimeException)
242 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
245 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
246 if ( m_bDisposed )
247 throw DisposedException();
250 com::sun::star::lang::EventObject aEvent( xThis );
251 m_aListenerContainer.disposeAndClear( aEvent );
253 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
254 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
255 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
256 while ( pIter != m_aListenerMap.end() )
260 Reference< XDispatch > xDispatch( pIter->second );
262 com::sun::star::util::URL aTargetURL;
263 aTargetURL.Complete = pIter->first;
264 if ( m_pImpl->m_xUrlTransformer.is() )
265 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
267 if ( xDispatch.is() && xStatusListener.is() )
268 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
270 catch ( Exception& )
274 ++pIter;
277 m_bDisposed = sal_True;
280 void SAL_CALL ToolboxController::addEventListener( const Reference< XEventListener >& xListener )
281 throw ( RuntimeException )
283 m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
286 void SAL_CALL ToolboxController::removeEventListener( const Reference< XEventListener >& aListener )
287 throw ( RuntimeException )
289 m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener );
292 // XEventListener
293 void SAL_CALL ToolboxController::disposing( const EventObject& Source )
294 throw ( RuntimeException )
296 Reference< XInterface > xSource( Source.Source );
298 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
300 if ( m_bDisposed )
301 return;
303 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
304 while ( pIter != m_aListenerMap.end() )
306 // Compare references and release dispatch references if they are equal.
307 Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
308 if ( xSource == xIfac )
309 pIter->second.clear();
310 ++pIter;
313 Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
314 if ( xIfac == xSource )
315 m_xFrame.clear();
318 // XStatusListener
319 void SAL_CALL ToolboxController::statusChanged( const FeatureStateEvent& )
320 throw ( RuntimeException )
322 // must be implemented by sub class
325 // XToolbarController
326 void SAL_CALL ToolboxController::execute( sal_Int16 KeyModifier )
327 throw (::com::sun::star::uno::RuntimeException)
329 Reference< XDispatch > xDispatch;
330 ::rtl::OUString aCommandURL;
333 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
335 if ( m_bDisposed )
336 throw DisposedException();
338 if ( m_bInitialized &&
339 m_xFrame.is() &&
340 m_xServiceManager.is() &&
341 m_aCommandURL.getLength() )
344 aCommandURL = m_aCommandURL;
345 URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
346 if ( pIter != m_aListenerMap.end() )
347 xDispatch = pIter->second;
351 if ( xDispatch.is() )
355 com::sun::star::util::URL aTargetURL;
356 Sequence<PropertyValue> aArgs( 1 );
358 // Provide key modifier information to dispatch function
359 aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
360 aArgs[0].Value = makeAny( KeyModifier );
362 aTargetURL.Complete = aCommandURL;
363 if ( m_pImpl->m_xUrlTransformer.is() )
364 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
365 xDispatch->dispatch( aTargetURL, aArgs );
367 catch ( DisposedException& )
373 void SAL_CALL ToolboxController::click()
374 throw (::com::sun::star::uno::RuntimeException)
378 void SAL_CALL ToolboxController::doubleClick()
379 throw (::com::sun::star::uno::RuntimeException)
383 Reference< XWindow > SAL_CALL ToolboxController::createPopupWindow()
384 throw (::com::sun::star::uno::RuntimeException)
386 return Reference< XWindow >();
389 Reference< XWindow > SAL_CALL ToolboxController::createItemWindow( const Reference< XWindow >& )
390 throw (::com::sun::star::uno::RuntimeException)
392 return Reference< XWindow >();
395 void ToolboxController::addStatusListener( const rtl::OUString& aCommandURL )
397 Reference< XDispatch > xDispatch;
398 Reference< XStatusListener > xStatusListener;
399 com::sun::star::util::URL aTargetURL;
402 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
403 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
405 // Already in the list of status listener. Do nothing.
406 if ( pIter != m_aListenerMap.end() )
407 return;
409 // Check if we are already initialized. Implementation starts adding itself as status listener when
410 // intialize is called.
411 if ( !m_bInitialized )
413 // Put into the hash_map of status listener. Will be activated when initialized is called
414 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
415 return;
417 else
419 // Add status listener directly as intialize has already been called.
420 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
421 if ( m_xServiceManager.is() && xDispatchProvider.is() )
423 aTargetURL.Complete = aCommandURL;
424 if ( m_pImpl->m_xUrlTransformer.is() )
425 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
426 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
428 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
429 URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
430 if ( aIter != m_aListenerMap.end() )
432 Reference< XDispatch > xOldDispatch( aIter->second );
433 aIter->second = xDispatch;
437 if ( xOldDispatch.is() )
438 xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
440 catch ( Exception& )
444 else
445 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
450 // Call without locked mutex as we are called back from dispatch implementation
453 if ( xDispatch.is() )
454 xDispatch->addStatusListener( xStatusListener, aTargetURL );
456 catch ( Exception& )
461 void ToolboxController::removeStatusListener( const rtl::OUString& aCommandURL )
463 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
465 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
466 if ( pIter != m_aListenerMap.end() )
468 Reference< XDispatch > xDispatch( pIter->second );
469 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
470 m_aListenerMap.erase( pIter );
474 com::sun::star::util::URL aTargetURL;
475 aTargetURL.Complete = aCommandURL;
476 if ( m_pImpl->m_xUrlTransformer.is() )
477 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
479 if ( xDispatch.is() && xStatusListener.is() )
480 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
482 catch ( Exception& )
488 void ToolboxController::bindListener()
490 std::vector< Listener > aDispatchVector;
491 Reference< XStatusListener > xStatusListener;
494 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
496 if ( !m_bInitialized )
497 return;
499 // Collect all registered command URL's and store them temporary
500 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
501 if ( m_xServiceManager.is() && xDispatchProvider.is() )
503 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
504 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
505 while ( pIter != m_aListenerMap.end() )
507 com::sun::star::util::URL aTargetURL;
508 aTargetURL.Complete = pIter->first;
509 if ( m_pImpl->m_xUrlTransformer.is() )
510 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
512 Reference< XDispatch > xDispatch( pIter->second );
513 if ( xDispatch.is() )
515 // We already have a dispatch object => we have to requery.
516 // Release old dispatch object and remove it as listener
519 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
521 catch ( Exception& )
526 pIter->second.clear();
527 xDispatch.clear();
529 // Query for dispatch object. Old dispatch will be released with this, too.
532 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
534 catch ( Exception& )
537 pIter->second = xDispatch;
539 Listener aListener( aTargetURL, xDispatch );
540 aDispatchVector.push_back( aListener );
541 ++pIter;
546 // Call without locked mutex as we are called back from dispatch implementation
547 if ( xStatusListener.is() )
551 for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
553 Listener& rListener = aDispatchVector[i];
554 if ( rListener.xDispatch.is() )
555 rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
556 else if ( rListener.aURL.Complete == m_aCommandURL )
560 // Send status changed for the main URL, if we cannot get a valid dispatch object.
561 // UI disables the button. Catch exception as we release our mutex, it is possible
562 // that someone else already disposed this instance!
563 FeatureStateEvent aFeatureStateEvent;
564 aFeatureStateEvent.IsEnabled = sal_False;
565 aFeatureStateEvent.FeatureURL = rListener.aURL;
566 aFeatureStateEvent.State = Any();
567 xStatusListener->statusChanged( aFeatureStateEvent );
569 catch ( Exception& )
575 catch ( Exception& )
581 void ToolboxController::unbindListener()
583 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
585 if ( !m_bInitialized )
586 return;
588 // Collect all registered command URL's and store them temporary
589 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
590 if ( m_xServiceManager.is() && xDispatchProvider.is() )
592 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
593 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
594 while ( pIter != m_aListenerMap.end() )
596 com::sun::star::util::URL aTargetURL;
597 aTargetURL.Complete = pIter->first;
598 if ( m_pImpl->m_xUrlTransformer.is() )
599 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
601 Reference< XDispatch > xDispatch( pIter->second );
602 if ( xDispatch.is() )
604 // We already have a dispatch object => we have to requery.
605 // Release old dispatch object and remove it as listener
608 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
610 catch ( Exception& )
614 pIter->second.clear();
615 ++pIter;
620 sal_Bool ToolboxController::isBound() const
622 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
624 if ( !m_bInitialized )
625 return sal_False;
627 URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL );
628 if ( pIter != m_aListenerMap.end() )
629 return ( pIter->second.is() );
631 return sal_False;
634 sal_Bool ToolboxController::hasBigImages() const
636 return SvtMiscOptions().AreCurrentSymbolsLarge();
639 sal_Bool ToolboxController::isHighContrast() const
641 sal_Bool bHighContrast( sal_False );
643 Reference< XWindow > xWindow = m_pImpl->m_xParentWindow;
644 if ( xWindow.is() )
646 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
647 Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
648 if ( pWindow )
649 bHighContrast = ( ((ToolBox *)pWindow)->GetBackground().GetColor().IsDark() );
652 return bHighContrast;
655 void ToolboxController::updateStatus()
657 bindListener();
660 void ToolboxController::updateStatus( const rtl::OUString aCommandURL )
662 Reference< XDispatch > xDispatch;
663 Reference< XStatusListener > xStatusListener;
664 com::sun::star::util::URL aTargetURL;
667 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
669 if ( !m_bInitialized )
670 return;
672 // Try to find a dispatch object for the requested command URL
673 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
674 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
675 if ( m_xServiceManager.is() && xDispatchProvider.is() )
677 aTargetURL.Complete = aCommandURL;
678 if ( m_pImpl->m_xUrlTransformer.is() )
679 m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
680 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 );
684 if ( xDispatch.is() && xStatusListener.is() )
686 // Catch exception as we release our mutex, it is possible that someone else
687 // has already disposed this instance!
688 // Add/remove status listener to get a update status information from the
689 // requested command.
692 xDispatch->addStatusListener( xStatusListener, aTargetURL );
693 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
695 catch ( Exception& )
701 Reference< XURLTransformer > ToolboxController::getURLTransformer() const
703 return m_pImpl->m_xUrlTransformer;
706 Reference< ::com::sun::star::awt::XWindow > ToolboxController::getParent() const
708 return m_pImpl->m_xParentWindow;
710 } // svt