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