merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / uno / framestatuslistener.cxx
blobeb2958b0788c88ee9129819c2d9af3b43823efac
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: framestatuslistener.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <framestatuslistener.hxx>
34 #include <com/sun/star/frame/XDispatchProvider.hpp>
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <vos/mutex.hxx>
37 #include <vcl/svapp.hxx>
39 using namespace ::cppu;
40 using namespace ::com::sun::star::awt;
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::util;
43 using namespace ::com::sun::star::beans;
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::frame;
47 namespace svt
50 FrameStatusListener::FrameStatusListener(
51 const Reference< XMultiServiceFactory >& rServiceManager,
52 const Reference< XFrame >& xFrame ) :
53 OWeakObject()
54 , m_bInitialized( sal_True )
55 , m_bDisposed( sal_False )
56 , m_xFrame( xFrame )
57 , m_xServiceManager( rServiceManager )
61 FrameStatusListener::~FrameStatusListener()
65 Reference< XFrame > FrameStatusListener::getFrameInterface() const
67 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
68 return m_xFrame;
71 Reference< XMultiServiceFactory > FrameStatusListener::getServiceManager() const
73 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
74 return m_xServiceManager;
77 // XInterface
78 Any SAL_CALL FrameStatusListener::queryInterface( const Type& rType )
79 throw ( RuntimeException )
81 Any a = ::cppu::queryInterface(
82 rType ,
83 static_cast< XComponent* >( this ),
84 static_cast< XFrameActionListener* >( this ),
85 static_cast< XStatusListener* >( this ),
86 static_cast< XEventListener* >( static_cast< XStatusListener* >( this )),
87 static_cast< XEventListener* >( static_cast< XFrameActionListener* >( this )));
89 if ( a.hasValue() )
90 return a;
92 return OWeakObject::queryInterface( rType );
95 void SAL_CALL FrameStatusListener::acquire() throw ()
97 OWeakObject::acquire();
100 void SAL_CALL FrameStatusListener::release() throw ()
102 OWeakObject::release();
105 // XComponent
106 void SAL_CALL FrameStatusListener::dispose()
107 throw (::com::sun::star::uno::RuntimeException)
109 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
111 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
112 if ( m_bDisposed )
113 throw DisposedException();
115 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
116 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
117 while ( pIter != m_aListenerMap.end() )
121 Reference< XDispatch > xDispatch( pIter->second );
122 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
123 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
124 "com.sun.star.util.URLTransformer" ))),
125 UNO_QUERY );
126 com::sun::star::util::URL aTargetURL;
127 aTargetURL.Complete = pIter->first;
128 xURLTransformer->parseStrict( aTargetURL );
130 if ( xDispatch.is() && xStatusListener.is() )
131 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
133 catch ( Exception& )
137 ++pIter;
140 m_bDisposed = sal_True;
143 void SAL_CALL FrameStatusListener::addEventListener( const Reference< XEventListener >& )
144 throw ( RuntimeException )
146 // helper class for status updates - no need to support listener
149 void SAL_CALL FrameStatusListener::removeEventListener( const Reference< XEventListener >& )
150 throw ( RuntimeException )
152 // helper class for status updates - no need to support listener
155 // XEventListener
156 void SAL_CALL FrameStatusListener::disposing( const EventObject& Source )
157 throw ( RuntimeException )
159 Reference< XInterface > xSource( Source.Source );
161 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
163 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
164 while ( pIter != m_aListenerMap.end() )
166 // Compare references and release dispatch references if they are equal.
167 Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
168 if ( xSource == xIfac )
169 pIter->second.clear();
172 Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
173 if ( xIfac == xSource )
174 m_xFrame.clear();
177 // XStatusListener
178 void SAL_CALL FrameStatusListener::statusChanged( const FeatureStateEvent& )
179 throw ( RuntimeException )
181 // must be implemented by sub class
184 void FrameStatusListener::frameAction( const FrameActionEvent& Action )
185 throw ( RuntimeException )
187 if ( Action.Action == FrameAction_CONTEXT_CHANGED )
188 bindListener();
191 void FrameStatusListener::addStatusListener( const rtl::OUString& aCommandURL )
193 Reference< XDispatch > xDispatch;
194 Reference< XStatusListener > xStatusListener;
195 com::sun::star::util::URL aTargetURL;
198 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
199 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
201 // Already in the list of status listener. Do nothing.
202 if ( pIter != m_aListenerMap.end() )
203 return;
205 // Check if we are already initialized. Implementation starts adding itself as status listener when
206 // intialize is called.
207 if ( !m_bInitialized )
209 // Put into the hash_map of status listener. Will be activated when initialized is called
210 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
211 return;
213 else
215 // Add status listener directly as intialize has already been called.
216 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
217 if ( m_xServiceManager.is() && xDispatchProvider.is() )
219 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
220 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
221 UNO_QUERY );
222 aTargetURL.Complete = aCommandURL;
223 xURLTransformer->parseStrict( aTargetURL );
224 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
226 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
227 URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
228 if ( aIter != m_aListenerMap.end() )
230 Reference< XDispatch > xOldDispatch( aIter->second );
231 aIter->second = xDispatch;
235 if ( xOldDispatch.is() )
236 xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
238 catch ( Exception& )
242 else
243 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
248 // Call without locked mutex as we are called back from dispatch implementation
251 if ( xDispatch.is() )
252 xDispatch->addStatusListener( xStatusListener, aTargetURL );
254 catch ( Exception& )
259 void FrameStatusListener::removeStatusListener( const rtl::OUString& aCommandURL )
261 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
263 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
264 if ( pIter != m_aListenerMap.end() )
266 Reference< XDispatch > xDispatch( pIter->second );
267 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
268 m_aListenerMap.erase( pIter );
272 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
273 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
274 UNO_QUERY );
275 com::sun::star::util::URL aTargetURL;
276 aTargetURL.Complete = aCommandURL;
277 xURLTransformer->parseStrict( aTargetURL );
279 if ( xDispatch.is() && xStatusListener.is() )
280 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
282 catch ( Exception& )
288 void FrameStatusListener::bindListener()
290 std::vector< Listener > aDispatchVector;
291 Reference< XStatusListener > xStatusListener;
294 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
296 if ( !m_bInitialized )
297 return;
299 // Collect all registered command URL's and store them temporary
300 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
301 if ( m_xServiceManager.is() && xDispatchProvider.is() )
303 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
304 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
305 while ( pIter != m_aListenerMap.end() )
307 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
308 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
309 UNO_QUERY );
310 com::sun::star::util::URL aTargetURL;
311 aTargetURL.Complete = pIter->first;
312 xURLTransformer->parseStrict( aTargetURL );
314 Reference< XDispatch > xDispatch( pIter->second );
315 if ( xDispatch.is() )
317 // We already have a dispatch object => we have to requery.
318 // Release old dispatch object and remove it as listener
321 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
323 catch ( Exception& )
328 // Query for dispatch object. Old dispatch will be released with this, too.
331 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
333 catch ( Exception& )
336 pIter->second = xDispatch;
338 Listener aListener( aTargetURL, xDispatch );
339 aDispatchVector.push_back( aListener );
340 ++pIter;
345 // Call without locked mutex as we are called back from dispatch implementation
346 if ( xStatusListener.is() )
350 for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
352 Listener& rListener = aDispatchVector[i];
353 if ( rListener.xDispatch.is() )
354 rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
357 catch ( Exception& )
363 void FrameStatusListener::unbindListener()
365 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
367 if ( !m_bInitialized )
368 return;
370 // Collect all registered command URL's and store them temporary
371 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
372 if ( m_xServiceManager.is() && xDispatchProvider.is() )
374 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
375 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
376 while ( pIter != m_aListenerMap.end() )
378 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
379 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
380 UNO_QUERY );
381 com::sun::star::util::URL aTargetURL;
382 aTargetURL.Complete = pIter->first;
383 xURLTransformer->parseStrict( aTargetURL );
385 Reference< XDispatch > xDispatch( pIter->second );
386 if ( xDispatch.is() )
388 // We already have a dispatch object => we have to requery.
389 // Release old dispatch object and remove it as listener
392 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
394 catch ( Exception& )
398 pIter->second.clear();
399 ++pIter;
404 void FrameStatusListener::updateStatus( const rtl::OUString aCommandURL )
406 Reference< XDispatch > xDispatch;
407 Reference< XStatusListener > xStatusListener;
408 com::sun::star::util::URL aTargetURL;
411 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
413 if ( !m_bInitialized )
414 return;
416 // Try to find a dispatch object for the requested command URL
417 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
418 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
419 if ( m_xServiceManager.is() && xDispatchProvider.is() )
421 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance(
422 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
423 UNO_QUERY );
424 aTargetURL.Complete = aCommandURL;
425 xURLTransformer->parseStrict( aTargetURL );
426 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 );
430 if ( xDispatch.is() && xStatusListener.is() )
432 // Catch exception as we release our mutex, it is possible that someone else
433 // has already disposed this instance!
434 // Add/remove status listener to get a update status information from the
435 // requested command.
438 xDispatch->addStatusListener( xStatusListener, aTargetURL );
439 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
441 catch ( Exception& )
447 } // svt