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