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