Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svtools/framestatuslistener.hxx>
30 : : #include <com/sun/star/frame/XDispatchProvider.hpp>
31 : : #include <com/sun/star/lang/DisposedException.hpp>
32 : : #include <com/sun/star/util/URLTransformer.hpp>
33 : : #include <osl/mutex.hxx>
34 : : #include <vcl/svapp.hxx>
35 : : #include <comphelper/componentcontext.hxx>
36 : :
37 : : using namespace ::cppu;
38 : : using namespace ::com::sun::star::awt;
39 : : using namespace ::com::sun::star::uno;
40 : : using namespace ::com::sun::star::util;
41 : : using namespace ::com::sun::star::beans;
42 : : using namespace ::com::sun::star::lang;
43 : : using namespace ::com::sun::star::frame;
44 : :
45 : : namespace svt
46 : : {
47 : :
48 : 2548 : FrameStatusListener::FrameStatusListener(
49 : : const Reference< XMultiServiceFactory >& rServiceManager,
50 : : const Reference< XFrame >& xFrame ) :
51 : : OWeakObject()
52 : : , m_bInitialized( sal_True )
53 : : , m_bDisposed( sal_False )
54 : : , m_xFrame( xFrame )
55 [ + - ][ + - ]: 2548 : , m_xServiceManager( rServiceManager )
56 : : {
57 : 2548 : }
58 : :
59 [ + - ][ + - ]: 2548 : FrameStatusListener::~FrameStatusListener()
[ + - ]
60 : : {
61 [ - + ]: 2548 : }
62 : :
63 : : // XInterface
64 : 10192 : Any SAL_CALL FrameStatusListener::queryInterface( const Type& rType )
65 : : throw ( RuntimeException )
66 : : {
67 : : Any a = ::cppu::queryInterface(
68 : : rType ,
69 : : static_cast< XComponent* >( this ),
70 : : static_cast< XFrameActionListener* >( this ),
71 : : static_cast< XStatusListener* >( this ),
72 : : static_cast< XEventListener* >( static_cast< XStatusListener* >( this )),
73 [ + - ]: 10192 : static_cast< XEventListener* >( static_cast< XFrameActionListener* >( this )));
74 : :
75 [ + - ]: 10192 : if ( a.hasValue() )
76 : 10192 : return a;
77 : :
78 [ # # ]: 10192 : return OWeakObject::queryInterface( rType );
79 : : }
80 : :
81 : 37218 : void SAL_CALL FrameStatusListener::acquire() throw ()
82 : : {
83 : 37218 : OWeakObject::acquire();
84 : 37218 : }
85 : :
86 : 37218 : void SAL_CALL FrameStatusListener::release() throw ()
87 : : {
88 : 37218 : OWeakObject::release();
89 : 37218 : }
90 : :
91 : : // XComponent
92 : 0 : void SAL_CALL FrameStatusListener::dispose()
93 : : throw (::com::sun::star::uno::RuntimeException)
94 : : {
95 [ # # ]: 0 : Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
96 : :
97 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
98 [ # # ]: 0 : if ( m_bDisposed )
99 [ # # ]: 0 : throw DisposedException();
100 : :
101 [ # # ]: 0 : Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
102 [ # # ]: 0 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
103 [ # # ][ # # ]: 0 : while ( pIter != m_aListenerMap.end() )
104 : : {
105 : : try
106 : : {
107 [ # # ]: 0 : Reference< XDispatch > xDispatch( pIter->second );
108 [ # # ][ # # ]: 0 : Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( ::comphelper::ComponentContext(m_xServiceManager).getUNOContext() ) );
[ # # ][ # # ]
109 : 0 : com::sun::star::util::URL aTargetURL;
110 [ # # ]: 0 : aTargetURL.Complete = pIter->first;
111 [ # # ][ # # ]: 0 : xURLTransformer->parseStrict( aTargetURL );
112 : :
113 [ # # ][ # # ]: 0 : if ( xDispatch.is() && xStatusListener.is() )
[ # # ]
114 [ # # ][ # # ]: 0 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
[ # # ]
115 : : }
116 [ # # ]: 0 : catch (const Exception&)
117 : : {
118 : : }
119 : :
120 : 0 : ++pIter;
121 : : }
122 : :
123 [ # # ]: 0 : m_bDisposed = sal_True;
124 : 0 : }
125 : :
126 : 0 : void SAL_CALL FrameStatusListener::addEventListener( const Reference< XEventListener >& )
127 : : throw ( RuntimeException )
128 : : {
129 : : // helper class for status updates - no need to support listener
130 : 0 : }
131 : :
132 : 0 : void SAL_CALL FrameStatusListener::removeEventListener( const Reference< XEventListener >& )
133 : : throw ( RuntimeException )
134 : : {
135 : : // helper class for status updates - no need to support listener
136 : 0 : }
137 : :
138 : : // XEventListener
139 : 0 : void SAL_CALL FrameStatusListener::disposing( const EventObject& Source )
140 : : throw ( RuntimeException )
141 : : {
142 : 0 : Reference< XInterface > xSource( Source.Source );
143 : :
144 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
145 : :
146 [ # # ]: 0 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
147 [ # # ][ # # ]: 0 : while ( pIter != m_aListenerMap.end() )
148 : : {
149 : : // Compare references and release dispatch references if they are equal.
150 [ # # ][ # # ]: 0 : Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
151 [ # # ][ # # ]: 0 : if ( xSource == xIfac )
152 [ # # ]: 0 : pIter->second.clear();
153 : 0 : }
154 : :
155 [ # # ]: 0 : Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
156 [ # # ][ # # ]: 0 : if ( xIfac == xSource )
157 [ # # ]: 0 : m_xFrame.clear();
158 : 0 : }
159 : :
160 : 0 : void FrameStatusListener::frameAction( const FrameActionEvent& Action )
161 : : throw ( RuntimeException )
162 : : {
163 [ # # ]: 0 : if ( Action.Action == FrameAction_CONTEXT_CHANGED )
164 : 0 : bindListener();
165 : 0 : }
166 : :
167 : 2548 : void FrameStatusListener::addStatusListener( const rtl::OUString& aCommandURL )
168 : : {
169 : 2548 : Reference< XDispatch > xDispatch;
170 : 2548 : Reference< XStatusListener > xStatusListener;
171 : 2548 : com::sun::star::util::URL aTargetURL;
172 : :
173 : : {
174 [ + - ]: 2548 : SolarMutexGuard aSolarMutexGuard;
175 [ + - ]: 2548 : URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
176 : :
177 : : // Already in the list of status listener. Do nothing.
178 [ + - ][ - + ]: 2548 : if ( pIter != m_aListenerMap.end() )
179 : : return;
180 : :
181 : : // Check if we are already initialized. Implementation starts adding itself as status listener when
182 : : // intialize is called.
183 [ - + ]: 2548 : if ( !m_bInitialized )
184 : : {
185 : : // Put into the boost::unordered_map of status listener. Will be activated when initialized is called
186 [ # # ][ # # ]: 0 : m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
[ # # ]
187 : : return;
188 : : }
189 : : else
190 : : {
191 : : // Add status listener directly as intialize has already been called.
192 [ + - ]: 2548 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
193 [ + - ][ + - ]: 2548 : if ( m_xServiceManager.is() && xDispatchProvider.is() )
[ + - ]
194 : : {
195 [ + - ][ + - ]: 2548 : Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( ::comphelper::ComponentContext(m_xServiceManager).getUNOContext() ) );
[ + - ][ + - ]
196 : 2548 : aTargetURL.Complete = aCommandURL;
197 [ + - ][ + - ]: 2548 : xURLTransformer->parseStrict( aTargetURL );
198 [ + - ][ + - ]: 2548 : xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
[ + - ]
199 : :
200 [ + - ][ # # ]: 2548 : xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
[ + - ]
201 [ + - ]: 2548 : URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
202 [ + - ][ - + ]: 2548 : if ( aIter != m_aListenerMap.end() )
203 : : {
204 [ # # ]: 0 : Reference< XDispatch > xOldDispatch( aIter->second );
205 [ # # ][ # # ]: 0 : aIter->second = xDispatch;
206 : :
207 : : try
208 : : {
209 [ # # ]: 0 : if ( xOldDispatch.is() )
210 [ # # ][ # # ]: 0 : xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
211 : : }
212 [ # # ]: 0 : catch (const Exception&)
213 : : {
214 : 0 : }
215 : : }
216 : : else
217 [ + - ][ + - ]: 2548 : m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
[ + - ]
218 : 2548 : }
219 [ + - ]: 2548 : }
[ + - # # ]
220 : : }
221 : :
222 : : // Call without locked mutex as we are called back from dispatch implementation
223 : : try
224 : : {
225 [ + + ]: 2548 : if ( xDispatch.is() )
226 [ + - ][ + - ]: 2548 : xDispatch->addStatusListener( xStatusListener, aTargetURL );
227 : : }
228 [ # # ]: 0 : catch (const Exception&)
229 : : {
230 [ - + ][ - + ]: 2548 : }
[ + - ]
231 : : }
232 : :
233 : :
234 : 2548 : void FrameStatusListener::bindListener()
235 : : {
236 [ + - ]: 2548 : std::vector< Listener > aDispatchVector;
237 : 2548 : Reference< XStatusListener > xStatusListener;
238 : :
239 : : {
240 [ + - ]: 2548 : SolarMutexGuard aSolarMutexGuard;
241 : :
242 [ - + ]: 2548 : if ( !m_bInitialized )
243 : 2548 : return;
244 : :
245 : : // Collect all registered command URL's and store them temporary
246 [ + - ]: 2548 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
247 [ + - ][ + - ]: 2548 : if ( m_xServiceManager.is() && xDispatchProvider.is() )
[ + - ]
248 : : {
249 [ + - ][ + - ]: 2548 : xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
250 [ + - ]: 2548 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
251 [ + - ][ + + ]: 5096 : while ( pIter != m_aListenerMap.end() )
252 : : {
253 [ + - ][ + - ]: 2548 : Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( ::comphelper::ComponentContext(m_xServiceManager).getUNOContext() ) );
[ + - ]
[ + - # # ]
254 : 2548 : com::sun::star::util::URL aTargetURL;
255 [ + - ]: 2548 : aTargetURL.Complete = pIter->first;
256 [ + - ][ + - ]: 2548 : xURLTransformer->parseStrict( aTargetURL );
257 : :
258 [ + - ]: 2548 : Reference< XDispatch > xDispatch( pIter->second );
259 [ + + ]: 2548 : if ( xDispatch.is() )
260 : : {
261 : : // We already have a dispatch object => we have to requery.
262 : : // Release old dispatch object and remove it as listener
263 : : try
264 : : {
265 [ + - ][ + - ]: 1532 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
266 : : }
267 [ # # ]: 0 : catch (const Exception&)
268 : : {
269 : : }
270 : : }
271 : :
272 : : // Query for dispatch object. Old dispatch will be released with this, too.
273 : : try
274 : : {
275 [ + - ][ + - ]: 2548 : xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
[ + - ][ # # ]
276 : : }
277 [ # # ]: 0 : catch (const Exception&)
278 : : {
279 : : }
280 [ + - ][ + - ]: 2548 : pIter->second = xDispatch;
281 : :
282 [ + - ]: 2548 : Listener aListener( aTargetURL, xDispatch );
283 [ + - ]: 2548 : aDispatchVector.push_back( aListener );
284 : 2548 : ++pIter;
285 [ + - ]: 2548 : }
286 [ + - ]: 2548 : }
[ + - # # ]
287 : : }
288 : :
289 : : // Call without locked mutex as we are called back from dispatch implementation
290 [ + - ]: 2548 : if ( xStatusListener.is() )
291 : : {
292 : : try
293 : : {
294 [ + + ]: 5096 : for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
295 : : {
296 [ + - ]: 2548 : Listener& rListener = aDispatchVector[i];
297 [ + + ]: 2548 : if ( rListener.xDispatch.is() )
298 [ + - ][ + - ]: 1532 : rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
299 : : }
300 : : }
301 [ # # ]: 0 : catch (const Exception&)
302 : : {
303 : : }
304 [ - + ][ + - ]: 2548 : }
305 : : }
306 : :
307 : 2548 : void FrameStatusListener::unbindListener()
308 : : {
309 [ + - ]: 2548 : SolarMutexGuard aSolarMutexGuard;
310 : :
311 [ - + ]: 2548 : if ( !m_bInitialized )
312 : 2548 : return;
313 : :
314 : : // Collect all registered command URL's and store them temporary
315 [ + - ]: 2548 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
316 [ + - ][ + - ]: 2548 : if ( m_xServiceManager.is() && xDispatchProvider.is() )
[ + - ]
317 : : {
318 [ + - ]: 2548 : Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
319 [ + - ]: 2548 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
320 [ + - ][ + + ]: 5096 : while ( pIter != m_aListenerMap.end() )
321 : : {
322 [ + - ][ + - ]: 2548 : Reference< XURLTransformer > xURLTransformer( com::sun::star::util::URLTransformer::create( ::comphelper::ComponentContext(m_xServiceManager).getUNOContext() ) );
[ + - ]
[ + - # # ]
323 : 2548 : com::sun::star::util::URL aTargetURL;
324 [ + - ]: 2548 : aTargetURL.Complete = pIter->first;
325 [ + - ][ + - ]: 2548 : xURLTransformer->parseStrict( aTargetURL );
326 : :
327 [ + - ]: 2548 : Reference< XDispatch > xDispatch( pIter->second );
328 [ + + ]: 2548 : if ( xDispatch.is() )
329 : : {
330 : : // We already have a dispatch object => we have to requery.
331 : : // Release old dispatch object and remove it as listener
332 : : try
333 : : {
334 [ + - ][ + - ]: 1532 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
335 : : }
336 [ # # ]: 0 : catch (const Exception&)
337 : : {
338 : : }
339 : : }
340 [ + - ]: 2548 : pIter->second.clear();
341 : 2548 : ++pIter;
342 : 5096 : }
343 [ + - ][ + - ]: 2548 : }
344 : : }
345 : :
346 : : } // svt
347 : :
348 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|