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