Bump version to 5.0-14
[LibreOffice.git] / svtools / source / uno / framestatuslistener.cxx
blob8173c10d1ad7e29ab1fff9ecbec3bb839b7008e5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svtools/framestatuslistener.hxx>
21 #include <com/sun/star/frame/XDispatchProvider.hpp>
22 #include <com/sun/star/lang/DisposedException.hpp>
23 #include <com/sun/star/util/URLTransformer.hpp>
24 #include <osl/mutex.hxx>
25 #include <cppuhelper/queryinterface.hxx>
26 #include <vcl/svapp.hxx>
27 #include <comphelper/processfactory.hxx>
29 using namespace ::cppu;
30 using namespace ::com::sun::star::awt;
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::util;
33 using namespace ::com::sun::star::beans;
34 using namespace ::com::sun::star::lang;
35 using namespace ::com::sun::star::frame;
37 namespace svt
40 FrameStatusListener::FrameStatusListener(
41 const Reference< XComponentContext >& rxContext,
42 const Reference< XFrame >& xFrame ) :
43 OWeakObject()
44 , m_bInitialized( true )
45 , m_bDisposed( false )
46 , m_xFrame( xFrame )
47 , m_xContext( rxContext )
51 FrameStatusListener::~FrameStatusListener()
55 // XInterface
56 Any SAL_CALL FrameStatusListener::queryInterface( const Type& rType )
57 throw ( RuntimeException, std::exception )
59 Any a = ::cppu::queryInterface(
60 rType ,
61 static_cast< XComponent* >( this ),
62 static_cast< XFrameActionListener* >( this ),
63 static_cast< XStatusListener* >( this ),
64 static_cast< XEventListener* >( static_cast< XStatusListener* >( this )),
65 static_cast< XEventListener* >( static_cast< XFrameActionListener* >( this )));
67 if ( a.hasValue() )
68 return a;
70 return OWeakObject::queryInterface( rType );
73 void SAL_CALL FrameStatusListener::acquire() throw ()
75 OWeakObject::acquire();
78 void SAL_CALL FrameStatusListener::release() throw ()
80 OWeakObject::release();
83 // XComponent
84 void SAL_CALL FrameStatusListener::dispose()
85 throw (::com::sun::star::uno::RuntimeException, std::exception)
87 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
89 SolarMutexGuard aSolarMutexGuard;
90 if ( m_bDisposed )
91 throw DisposedException();
93 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
94 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
95 while ( pIter != m_aListenerMap.end() )
97 try
99 Reference< XDispatch > xDispatch( pIter->second );
100 Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( m_xContext ) );
101 com::sun::star::util::URL aTargetURL;
102 aTargetURL.Complete = pIter->first;
103 xURLTransformer->parseStrict( aTargetURL );
105 if ( xDispatch.is() && xStatusListener.is() )
106 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
108 catch (const Exception&)
112 ++pIter;
115 m_bDisposed = true;
118 void SAL_CALL FrameStatusListener::addEventListener( const Reference< XEventListener >& )
119 throw ( RuntimeException, std::exception )
121 // helper class for status updates - no need to support listener
124 void SAL_CALL FrameStatusListener::removeEventListener( const Reference< XEventListener >& )
125 throw ( RuntimeException, std::exception )
127 // helper class for status updates - no need to support listener
130 // XEventListener
131 void SAL_CALL FrameStatusListener::disposing( const EventObject& Source )
132 throw ( RuntimeException, std::exception )
134 Reference< XInterface > xSource( Source.Source );
136 SolarMutexGuard aSolarMutexGuard;
138 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
139 while ( pIter != m_aListenerMap.end() )
141 // Compare references and release dispatch references if they are equal.
142 Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
143 if ( xSource == xIfac )
144 pIter->second.clear();
147 Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
148 if ( xIfac == xSource )
149 m_xFrame.clear();
152 void FrameStatusListener::frameAction( const FrameActionEvent& Action )
153 throw ( RuntimeException, std::exception )
155 if ( Action.Action == FrameAction_CONTEXT_CHANGED )
156 bindListener();
159 void FrameStatusListener::addStatusListener( const OUString& aCommandURL )
161 Reference< XDispatch > xDispatch;
162 Reference< XStatusListener > xStatusListener;
163 com::sun::star::util::URL aTargetURL;
166 SolarMutexGuard aSolarMutexGuard;
167 URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
169 // Already in the list of status listener. Do nothing.
170 if ( pIter != m_aListenerMap.end() )
171 return;
173 // Check if we are already initialized. Implementation starts adding itself as status listener when
174 // intialize is called.
175 if ( !m_bInitialized )
177 // Put into the unordered_map of status listener. Will be activated when initialized is called
178 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
179 return;
181 else
183 // Add status listener directly as intialize has already been called.
184 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
185 if ( m_xContext.is() && xDispatchProvider.is() )
187 Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( m_xContext ) );
188 aTargetURL.Complete = aCommandURL;
189 xURLTransformer->parseStrict( aTargetURL );
190 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
192 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
193 URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
194 if ( aIter != m_aListenerMap.end() )
196 Reference< XDispatch > xOldDispatch( aIter->second );
197 aIter->second = xDispatch;
201 if ( xOldDispatch.is() )
202 xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
204 catch (const Exception&)
208 else
209 m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
214 // Call without locked mutex as we are called back from dispatch implementation
217 if ( xDispatch.is() )
218 xDispatch->addStatusListener( xStatusListener, aTargetURL );
220 catch (const Exception&)
226 void FrameStatusListener::bindListener()
228 std::vector< Listener > aDispatchVector;
229 Reference< XStatusListener > xStatusListener;
232 SolarMutexGuard aSolarMutexGuard;
234 if ( !m_bInitialized )
235 return;
237 // Collect all registered command URL's and store them temporary
238 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
239 if ( m_xContext.is() && xDispatchProvider.is() )
241 xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
242 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
243 while ( pIter != m_aListenerMap.end() )
245 Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( m_xContext ) );
246 com::sun::star::util::URL aTargetURL;
247 aTargetURL.Complete = pIter->first;
248 xURLTransformer->parseStrict( aTargetURL );
250 Reference< XDispatch > xDispatch( pIter->second );
251 if ( xDispatch.is() )
253 // We already have a dispatch object => we have to requery.
254 // Release old dispatch object and remove it as listener
257 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
259 catch (const Exception&)
264 // Query for dispatch object. Old dispatch will be released with this, too.
267 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
269 catch (const Exception&)
272 pIter->second = xDispatch;
274 Listener aListener( aTargetURL, xDispatch );
275 aDispatchVector.push_back( aListener );
276 ++pIter;
281 // Call without locked mutex as we are called back from dispatch implementation
282 if ( xStatusListener.is() )
286 for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
288 Listener& rListener = aDispatchVector[i];
289 if ( rListener.xDispatch.is() )
290 rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
293 catch (const Exception&)
299 void FrameStatusListener::unbindListener()
301 SolarMutexGuard aSolarMutexGuard;
303 if ( !m_bInitialized )
304 return;
306 // Collect all registered command URL's and store them temporary
307 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
308 if ( m_xContext.is() && xDispatchProvider.is() )
310 Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
311 URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
312 while ( pIter != m_aListenerMap.end() )
314 Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( m_xContext ) );
315 com::sun::star::util::URL aTargetURL;
316 aTargetURL.Complete = pIter->first;
317 xURLTransformer->parseStrict( aTargetURL );
319 Reference< XDispatch > xDispatch( pIter->second );
320 if ( xDispatch.is() )
322 // We already have a dispatch object => we have to requery.
323 // Release old dispatch object and remove it as listener
326 xDispatch->removeStatusListener( xStatusListener, aTargetURL );
328 catch (const Exception&)
332 pIter->second.clear();
333 ++pIter;
338 } // svt
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */