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