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