1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <svtools/toolboxcontroller.hxx>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/frame/XDispatchProvider.hpp>
34 #include <com/sun/star/lang/DisposedException.hpp>
35 #include <com/sun/star/frame/XLayoutManager.hpp>
36 #include <vos/mutex.hxx>
37 #include <vcl/svapp.hxx>
38 #include <svtools/imgdef.hxx>
39 #include <svtools/miscopt.hxx>
40 #include <toolkit/unohlp.hxx>
41 #include <vcl/toolbox.hxx>
42 //shizhobo
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 const int TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE  = 1;
45 const int TOOLBARCONTROLLER_PROPCOUNT               = 1;
46 const rtl::OUString TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE( RTL_CONSTASCII_USTRINGPARAM( "SupportsVisiable" ));
47 //end
48 
49 using ::rtl::OUString;
50 
51 using namespace ::cppu;
52 using namespace ::com::sun::star::awt;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::util;
55 using namespace ::com::sun::star::beans;
56 using namespace ::com::sun::star::lang;
57 using namespace ::com::sun::star::frame;
58 using namespace ::com::sun::star::frame;
59 
60 namespace svt
61 {
62 
63 struct DispatchInfo
64 {
65 	Reference< XDispatch > mxDispatch;
66 	const URL maURL;
67 	const Sequence< PropertyValue > maArgs;
68 
69 	DispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
70 		: mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
71 };
72 
73 struct ToolboxController_Impl
74 {
75 	::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >          m_xParentWindow;
76 	::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xUrlTransformer;
77 	rtl::OUString m_sModuleName;
78 	 sal_uInt16 m_nToolBoxId;
79 
80 	DECL_STATIC_LINK( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo* );
81 
82 	ToolboxController_Impl()
83 		: m_nToolBoxId( SAL_MAX_UINT16 )
84 	{}
85 };
86 
87 ToolboxController::ToolboxController(
88 
89     const Reference< XMultiServiceFactory >& rServiceManager,
90     const Reference< XFrame >& xFrame,
91     const ::rtl::OUString& aCommandURL ) :
92     OPropertyContainer(GetBroadcastHelper())
93     ,	OWeakObject()
94     ,   m_bInitialized( sal_False )
95     ,   m_bDisposed( sal_False )
96 	,	m_xFrame(xFrame)
97     ,   m_xServiceManager( rServiceManager )
98     ,   m_aCommandURL( aCommandURL )
99     ,   m_aListenerContainer( m_aMutex )
100 {
101 	//registger Propertyh by shizhoubo
102 	registerProperty(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE, TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE, com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY,
103 		&m_bSupportVisiable, getCppuType(&m_bSupportVisiable));
104 
105 	m_pImpl = new ToolboxController_Impl;
106 
107 	try
108 	{
109 		m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance(
110                                                             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
111                                                         UNO_QUERY );
112 	}
113 	catch(const Exception&)
114 	{
115 	}
116 }
117 
118 ToolboxController::ToolboxController() :
119     OPropertyContainer(GetBroadcastHelper())
120     ,	OWeakObject()
121     ,   m_bInitialized( sal_False )
122     ,   m_bDisposed( sal_False )
123     ,   m_aListenerContainer( m_aMutex )
124 {
125 	//registger Propertyh by shizhoubo
126 	registerProperty(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE, TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE, com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY,
127 		&m_bSupportVisiable, getCppuType(&m_bSupportVisiable));
128 
129 	m_pImpl = new ToolboxController_Impl;
130 }
131 
132 ToolboxController::~ToolboxController()
133 {
134 	delete m_pImpl;
135 }
136 
137 Reference< XFrame > ToolboxController::getFrameInterface() const
138 {
139     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
140     return m_xFrame;
141 }
142 
143 Reference< XMultiServiceFactory > ToolboxController::getServiceManager() const
144 {
145     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
146     return m_xServiceManager;
147 }
148 
149 Reference< XLayoutManager > ToolboxController::getLayoutManager() const
150 {
151     Reference< XLayoutManager > xLayoutManager;
152     Reference< XPropertySet > xPropSet;
153     {
154         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
155         xPropSet = Reference< XPropertySet >( m_xFrame, UNO_QUERY );
156     }
157 
158     if ( xPropSet.is() )
159     {
160         try
161         {
162             xLayoutManager.set(xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY);
163         }
164         catch ( Exception& )
165         {
166         }
167     }
168 
169     return xLayoutManager;
170 }
171 
172 // XInterface
173 Any SAL_CALL ToolboxController::queryInterface( const Type& rType )
174 throw ( RuntimeException )
175 {
176 	Any a = ::cppu::queryInterface(
177 				rType ,
178 				static_cast< XToolbarController* >( this ),
179 				static_cast< XStatusListener* >( this ),
180 				static_cast< XEventListener* >( this ),
181 				static_cast< XInitialization* >( this ),
182                 static_cast< XComponent* >( this ),
183                 static_cast< XUpdatable* >( this ));
184     if ( !a.hasValue())
185 	{
186 		a = ::cppu::queryInterface(rType
187 			,static_cast<XPropertySet*>(this)
188 			,static_cast<XMultiPropertySet*>(this)
189 			,static_cast<XFastPropertySet*>(this));
190 		if (!a.hasValue())
191 			return OWeakObject::queryInterface( rType );
192 	}
193 	return a;
194 }
195 
196 void SAL_CALL ToolboxController::acquire() throw ()
197 {
198     OWeakObject::acquire();
199 }
200 
201 void SAL_CALL ToolboxController::release() throw ()
202 {
203     OWeakObject::release();
204 }
205 
206 void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments )
207 throw ( Exception, RuntimeException )
208 {
209     bool bInitialized( true );
210 
211     {
212         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
213 
214         if ( m_bDisposed )
215             throw DisposedException();
216 
217         bInitialized = m_bInitialized;
218     }
219 
220     if ( !bInitialized )
221     {
222         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
223         m_bInitialized = sal_True;
224         //shizhoubo add
225         m_bSupportVisiable = sal_False;
226         PropertyValue aPropValue;
227         for ( int i = 0; i < aArguments.getLength(); i++ )
228         {
229             if ( aArguments[i] >>= aPropValue )
230             {
231                 if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Frame") ))
232 					m_xFrame.set(aPropValue.Value,UNO_QUERY);
233                 else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CommandURL") ))
234                     aPropValue.Value >>= m_aCommandURL;
235                 else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ServiceManager") ))
236 					m_xServiceManager.set(aPropValue.Value,UNO_QUERY);
237                 else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ))
238 					m_pImpl->m_xParentWindow.set(aPropValue.Value,UNO_QUERY);
239 				else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ModuleName" ) ) )
240 					aPropValue.Value >>= m_pImpl->m_sModuleName;
241             }
242         }
243 
244 		try
245 		{
246 			if ( !m_pImpl->m_xUrlTransformer.is() && m_xServiceManager.is() )
247 				m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance(
248 																rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
249 															UNO_QUERY );
250 		}
251 		catch(const Exception&)
252 		{
253 		}
254 
255         if ( m_aCommandURL.getLength() )
256             m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() ));
257     }
258 }
259 
260 void SAL_CALL ToolboxController::update()
261 throw ( RuntimeException )
262 {
263     {
264         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
265         if ( m_bDisposed )
266             throw DisposedException();
267     }
268 
269     // Bind all registered listeners to their dispatch objects
270     bindListener();
271 }
272 
273 // XComponent
274 void SAL_CALL ToolboxController::dispose()
275 throw (::com::sun::star::uno::RuntimeException)
276 {
277     Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
278 
279     {
280         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
281         if ( m_bDisposed )
282             throw DisposedException();
283     }
284 
285     com::sun::star::lang::EventObject aEvent( xThis );
286     m_aListenerContainer.disposeAndClear( aEvent );
287 
288     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
289     Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
290     URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
291     while ( pIter != m_aListenerMap.end() )
292     {
293         try
294         {
295             Reference< XDispatch > xDispatch( pIter->second );
296 
297             com::sun::star::util::URL aTargetURL;
298             aTargetURL.Complete = pIter->first;
299 			if ( m_pImpl->m_xUrlTransformer.is() )
300 				m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
301 
302             if ( xDispatch.is() && xStatusListener.is() )
303                 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
304         }
305         catch ( Exception& )
306         {
307         }
308 
309         ++pIter;
310     }
311 
312     m_bDisposed = sal_True;
313 }
314 
315 void SAL_CALL ToolboxController::addEventListener( const Reference< XEventListener >& xListener )
316 throw ( RuntimeException )
317 {
318     m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
319 }
320 
321 void SAL_CALL ToolboxController::removeEventListener( const Reference< XEventListener >& aListener )
322 throw ( RuntimeException )
323 {
324     m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener );
325 }
326 
327 // XEventListener
328 void SAL_CALL ToolboxController::disposing( const EventObject& Source )
329 throw ( RuntimeException )
330 {
331     Reference< XInterface > xSource( Source.Source );
332 
333     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
334 
335     if ( m_bDisposed )
336         return;
337 
338     URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
339     while ( pIter != m_aListenerMap.end() )
340     {
341         // Compare references and release dispatch references if they are equal.
342         Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
343         if ( xSource == xIfac )
344             pIter->second.clear();
345 		++pIter;
346     }
347 
348     Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
349     if ( xIfac == xSource )
350         m_xFrame.clear();
351 }
352 
353 // XStatusListener
354 void SAL_CALL ToolboxController::statusChanged( const FeatureStateEvent& )
355 throw ( RuntimeException )
356 {
357     // must be implemented by sub class
358 }
359 
360 // XToolbarController
361 void SAL_CALL ToolboxController::execute( sal_Int16 KeyModifier )
362 throw (::com::sun::star::uno::RuntimeException)
363 {
364     Reference< XDispatch >       xDispatch;
365     ::rtl::OUString                     aCommandURL;
366 
367     {
368         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
369 
370         if ( m_bDisposed )
371             throw DisposedException();
372 
373         if ( m_bInitialized &&
374              m_xFrame.is() &&
375              m_xServiceManager.is() &&
376              m_aCommandURL.getLength() )
377         {
378 
379             aCommandURL = m_aCommandURL;
380             URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
381             if ( pIter != m_aListenerMap.end() )
382                 xDispatch = pIter->second;
383         }
384     }
385 
386     if ( xDispatch.is() )
387     {
388         try
389         {
390             com::sun::star::util::URL aTargetURL;
391             Sequence<PropertyValue>   aArgs( 1 );
392 
393             // Provide key modifier information to dispatch function
394             aArgs[0].Name   = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
395             aArgs[0].Value  = makeAny( KeyModifier );
396 
397             aTargetURL.Complete = aCommandURL;
398 			if ( m_pImpl->m_xUrlTransformer.is() )
399 				m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
400             xDispatch->dispatch( aTargetURL, aArgs );
401         }
402         catch ( DisposedException& )
403         {
404         }
405     }
406 }
407 
408 void SAL_CALL ToolboxController::click()
409 throw (::com::sun::star::uno::RuntimeException)
410 {
411 }
412 
413 void SAL_CALL ToolboxController::doubleClick()
414 throw (::com::sun::star::uno::RuntimeException)
415 {
416 }
417 
418 Reference< XWindow > SAL_CALL ToolboxController::createPopupWindow()
419 throw (::com::sun::star::uno::RuntimeException)
420 {
421     return Reference< XWindow >();
422 }
423 
424 Reference< XWindow > SAL_CALL ToolboxController::createItemWindow( const Reference< XWindow >& )
425 throw (::com::sun::star::uno::RuntimeException)
426 {
427     return Reference< XWindow >();
428 }
429 
430 void ToolboxController::addStatusListener( const rtl::OUString& aCommandURL )
431 {
432     Reference< XDispatch >       xDispatch;
433     Reference< XStatusListener > xStatusListener;
434     com::sun::star::util::URL    aTargetURL;
435 
436     {
437         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
438         URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
439 
440         // Already in the list of status listener. Do nothing.
441         if ( pIter != m_aListenerMap.end() )
442             return;
443 
444         // Check if we are already initialized. Implementation starts adding itself as status listener when
445         // intialize is called.
446         if ( !m_bInitialized )
447         {
448             // Put into the hash_map of status listener. Will be activated when initialized is called
449             m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
450             return;
451         }
452         else
453         {
454             // Add status listener directly as intialize has already been called.
455             Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
456             if ( m_xServiceManager.is() && xDispatchProvider.is() )
457             {
458                 aTargetURL.Complete = aCommandURL;
459                 if ( m_pImpl->m_xUrlTransformer.is() )
460 					m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
461                 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
462 
463                 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
464                 URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
465                 if ( aIter != m_aListenerMap.end() )
466                 {
467                     Reference< XDispatch > xOldDispatch( aIter->second );
468                     aIter->second = xDispatch;
469 
470                     try
471                     {
472                         if ( xOldDispatch.is() )
473                             xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
474                     }
475                     catch ( Exception& )
476                     {
477                     }
478                 }
479                 else
480                     m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
481             }
482         }
483     }
484 
485     // Call without locked mutex as we are called back from dispatch implementation
486     try
487     {
488         if ( xDispatch.is() )
489             xDispatch->addStatusListener( xStatusListener, aTargetURL );
490     }
491     catch ( Exception& )
492     {
493     }
494 }
495 
496 void ToolboxController::removeStatusListener( const rtl::OUString& aCommandURL )
497 {
498     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
499 
500     URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
501     if ( pIter != m_aListenerMap.end() )
502     {
503         Reference< XDispatch > xDispatch( pIter->second );
504         Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
505         m_aListenerMap.erase( pIter );
506 
507         try
508         {
509             com::sun::star::util::URL aTargetURL;
510             aTargetURL.Complete = aCommandURL;
511             if ( m_pImpl->m_xUrlTransformer.is() )
512 				m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
513 
514             if ( xDispatch.is() && xStatusListener.is() )
515                 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
516         }
517         catch ( Exception& )
518         {
519         }
520     }
521 }
522 
523 void ToolboxController::bindListener()
524 {
525     std::vector< Listener > aDispatchVector;
526     Reference< XStatusListener > xStatusListener;
527 
528     {
529         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
530 
531         if ( !m_bInitialized )
532             return;
533 
534         // Collect all registered command URL's and store them temporary
535         Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
536         if ( m_xServiceManager.is() && xDispatchProvider.is() )
537         {
538             xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
539             URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
540             while ( pIter != m_aListenerMap.end() )
541             {
542                 com::sun::star::util::URL aTargetURL;
543                 aTargetURL.Complete = pIter->first;
544                 if ( m_pImpl->m_xUrlTransformer.is() )
545 					m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
546 
547                 Reference< XDispatch > xDispatch( pIter->second );
548                 if ( xDispatch.is() )
549                 {
550                     // We already have a dispatch object => we have to requery.
551                     // Release old dispatch object and remove it as listener
552                     try
553                     {
554                         xDispatch->removeStatusListener( xStatusListener, aTargetURL );
555                     }
556                     catch ( Exception& )
557                     {
558                     }
559                 }
560 
561                 pIter->second.clear();
562                 xDispatch.clear();
563 
564                 // Query for dispatch object. Old dispatch will be released with this, too.
565                 try
566                 {
567                     xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
568                 }
569                 catch ( Exception& )
570                 {
571                 }
572                 pIter->second = xDispatch;
573 
574                 Listener aListener( aTargetURL, xDispatch );
575                 aDispatchVector.push_back( aListener );
576                 ++pIter;
577             }
578         }
579     }
580 
581     // Call without locked mutex as we are called back from dispatch implementation
582     if ( xStatusListener.is() )
583     {
584         try
585         {
586             for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
587             {
588                 Listener& rListener = aDispatchVector[i];
589                 if ( rListener.xDispatch.is() )
590                     rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
591                 else if ( rListener.aURL.Complete == m_aCommandURL )
592                 {
593                     try
594                     {
595                         // Send status changed for the main URL, if we cannot get a valid dispatch object.
596                         // UI disables the button. Catch exception as we release our mutex, it is possible
597                         // that someone else already disposed this instance!
598                         FeatureStateEvent aFeatureStateEvent;
599                         aFeatureStateEvent.IsEnabled = sal_False;
600                         aFeatureStateEvent.FeatureURL = rListener.aURL;
601                         aFeatureStateEvent.State = Any();
602                         xStatusListener->statusChanged( aFeatureStateEvent );
603                     }
604                     catch ( Exception& )
605                     {
606                     }
607                 }
608             }
609         }
610         catch ( Exception& )
611         {
612         }
613     }
614 }
615 
616 void ToolboxController::unbindListener()
617 {
618     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
619 
620     if ( !m_bInitialized )
621         return;
622 
623     // Collect all registered command URL's and store them temporary
624     Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
625     if ( m_xServiceManager.is() && xDispatchProvider.is() )
626     {
627         Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
628         URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
629         while ( pIter != m_aListenerMap.end() )
630         {
631             com::sun::star::util::URL aTargetURL;
632             aTargetURL.Complete = pIter->first;
633             if ( m_pImpl->m_xUrlTransformer.is() )
634 				m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
635 
636             Reference< XDispatch > xDispatch( pIter->second );
637             if ( xDispatch.is() )
638             {
639                 // We already have a dispatch object => we have to requery.
640                 // Release old dispatch object and remove it as listener
641                 try
642                 {
643                     xDispatch->removeStatusListener( xStatusListener, aTargetURL );
644                 }
645                 catch ( Exception& )
646                 {
647                 }
648             }
649             pIter->second.clear();
650             ++pIter;
651         }
652     }
653 }
654 
655 sal_Bool ToolboxController::isBound() const
656 {
657     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
658 
659     if ( !m_bInitialized )
660         return sal_False;
661 
662     URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL );
663     if ( pIter != m_aListenerMap.end() )
664         return ( pIter->second.is() );
665 
666     return sal_False;
667 }
668 
669 sal_Bool ToolboxController::hasBigImages() const
670 {
671     return SvtMiscOptions().AreCurrentSymbolsLarge();
672 }
673 
674 sal_Bool ToolboxController::isHighContrast() const
675 {
676     sal_Bool bHighContrast( sal_False );
677 
678     Reference< XWindow > xWindow = m_pImpl->m_xParentWindow;
679     if ( xWindow.is() )
680     {
681         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
682         Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
683         if ( pWindow )
684 	        bHighContrast = ( ((ToolBox *)pWindow)->GetSettings().GetStyleSettings().GetHighContrastMode() );
685     }
686 
687     return bHighContrast;
688 }
689 
690 void ToolboxController::updateStatus()
691 {
692     bindListener();
693 }
694 
695 void ToolboxController::updateStatus( const rtl::OUString aCommandURL )
696 {
697     Reference< XDispatch > xDispatch;
698     Reference< XStatusListener > xStatusListener;
699     com::sun::star::util::URL aTargetURL;
700 
701     {
702         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
703 
704         if ( !m_bInitialized )
705             return;
706 
707         // Try to find a dispatch object for the requested command URL
708         Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
709         xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
710         if ( m_xServiceManager.is() && xDispatchProvider.is() )
711         {
712             aTargetURL.Complete = aCommandURL;
713             if ( m_pImpl->m_xUrlTransformer.is() )
714 				m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL );
715             xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 );
716         }
717     }
718 
719     if ( xDispatch.is() && xStatusListener.is() )
720     {
721         // Catch exception as we release our mutex, it is possible that someone else
722         // has already disposed this instance!
723         // Add/remove status listener to get a update status information from the
724         // requested command.
725         try
726         {
727             xDispatch->addStatusListener( xStatusListener, aTargetURL );
728             xDispatch->removeStatusListener( xStatusListener, aTargetURL );
729         }
730         catch ( Exception& )
731         {
732         }
733     }
734 }
735 
736 Reference< XURLTransformer > ToolboxController::getURLTransformer() const
737 {
738 	return m_pImpl->m_xUrlTransformer;
739 }
740 
741 Reference< ::com::sun::star::awt::XWindow > ToolboxController::getParent() const
742 {
743 	return m_pImpl->m_xParentWindow;
744 }
745 
746 const rtl::OUString& ToolboxController::getModuleName() const
747 {
748 	return m_pImpl->m_sModuleName;
749 }
750 
751 void ToolboxController::dispatchCommand( const OUString& sCommandURL, const Sequence< PropertyValue >& rArgs )
752 {
753     try
754     {
755 	    Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
756         URL aURL;
757         aURL.Complete = sCommandURL;
758         getURLTransformer()->parseStrict( aURL );
759 
760 		Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
761 
762         Application::PostUserEvent( STATIC_LINK(0, ToolboxController_Impl, ExecuteHdl_Impl), new DispatchInfo( xDispatch, aURL, rArgs ) );
763 
764     }
765 	catch( Exception& )
766 	{
767 	}
768 }
769 
770 //
771 //-------------------------------------------------------------------------
772 // XPropertySet by shizhoubo
773 com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >  SAL_CALL ToolboxController::getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException)
774 {
775 	Reference<XPropertySetInfo>  xInfo( createPropertySetInfo( getInfoHelper() ) );
776 	return xInfo;
777 }
778 //-------------------------------------------------------------------------
779 ::cppu::IPropertyArrayHelper& ToolboxController::getInfoHelper()
780 {
781 		return *const_cast<ToolboxController*>(this)->getArrayHelper();
782 }
783 //OPropertyArrayUsageHelper by shizhoubo
784 //------------------------------------------------------------------------------
785 ::cppu::IPropertyArrayHelper* ToolboxController::createArrayHelper( ) const
786 {
787 		com::sun::star::uno::Sequence< Property > aProps;
788 		describeProperties(aProps);
789 		return new ::cppu::OPropertyArrayHelper(aProps);
790 }
791 //shizhoubo for supportsvisiable
792 void ToolboxController::setSupportVisiableProperty(sal_Bool bValue)
793 {
794 	m_bSupportVisiable = bValue;
795 }
796 //OPropertySetHelper by shizhoubo
797 sal_Bool SAL_CALL ToolboxController::convertFastPropertyValue( com::sun::star::uno::Any&    aConvertedValue ,
798                                              com::sun::star::uno::Any&        aOldValue       ,
799                                              sal_Int32                        nHandle         ,
800                                              const com::sun::star::uno::Any&  aValue          ) throw( com::sun::star::lang::IllegalArgumentException )
801 {
802 	switch (nHandle)
803 	{
804 		case TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE:
805 		{
806 			sal_Bool aNewValue(sal_False);
807 			aValue >>= aNewValue;
808 			if (aNewValue != m_bSupportVisiable)
809 			{
810 				aConvertedValue <<= aNewValue;
811 				aOldValue <<= m_bSupportVisiable;
812 				return sal_True;
813 			}
814 			return sal_False;
815 		}
816 	}
817 	return OPropertyContainer::convertFastPropertyValue(aConvertedValue, aOldValue, nHandle, aValue);
818 }
819 
820 void SAL_CALL ToolboxController::setFastPropertyValue_NoBroadcast(
821     sal_Int32                       nHandle,
822     const com::sun::star::uno::Any& aValue )
823 throw( com::sun::star::uno::Exception)
824 {
825     OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, aValue);
826     if (TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE == nHandle)
827     {
828         sal_Bool rValue(sal_False);
829         if (( aValue >>= rValue ) && m_bInitialized)
830             this->setSupportVisiableProperty( rValue );
831     }
832 }
833 
834 //--------------------------------------------------------------------
835 
836 IMPL_STATIC_LINK_NOINSTANCE( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo*, pDispatchInfo )
837 {
838 	pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
839     delete pDispatchInfo;
840     return 0;
841 }
842 
843 void ToolboxController::enable( bool bEnable )
844 {
845 	ToolBox* pToolBox = 0;
846 	sal_uInt16 nItemId = 0;
847 	if( getToolboxId( nItemId, &pToolBox ) )
848 	{
849 		pToolBox->EnableItem( nItemId, bEnable ? sal_True : sal_False );
850 	}
851 }
852 
853 bool ToolboxController::getToolboxId( sal_uInt16& rItemId, ToolBox** ppToolBox )
854 {
855 	if( (m_pImpl->m_nToolBoxId != SAL_MAX_UINT16) && (ppToolBox == 0) )
856 		return m_pImpl->m_nToolBoxId;
857 
858 	ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
859 
860 	if( (m_pImpl->m_nToolBoxId == SAL_MAX_UINT16) && pToolBox )
861 	{
862         const sal_uInt16 nCount = pToolBox->GetItemCount();
863 		for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
864 		{
865 			const sal_uInt16 nItemId = pToolBox->GetItemId( nPos );
866 			if ( pToolBox->GetItemCommand( nItemId ) == String( m_aCommandURL ) )
867 			{
868 				m_pImpl->m_nToolBoxId = nItemId;
869 				break;
870 			}
871 		}
872 	}
873 
874 	if( ppToolBox )
875 		*ppToolBox = pToolBox;
876 
877 	rItemId = m_pImpl->m_nToolBoxId;
878 
879 	return (rItemId != SAL_MAX_UINT16) && (( ppToolBox == 0) || (*ppToolBox != 0) );
880 }
881 //end
882 
883 } // svt
884