Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <svtools/toolboxcontroller.hxx>
21 : #include <com/sun/star/beans/PropertyAttribute.hpp>
22 : #include <com/sun/star/beans/PropertyValue.hpp>
23 : #include <com/sun/star/beans/XPropertySet.hpp>
24 : #include <com/sun/star/frame/XDispatchProvider.hpp>
25 : #include <com/sun/star/lang/DisposedException.hpp>
26 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 : #include <com/sun/star/frame/XLayoutManager.hpp>
28 : #include <com/sun/star/util/URLTransformer.hpp>
29 : #include <osl/mutex.hxx>
30 : #include <vcl/svapp.hxx>
31 : #include <svtools/imgdef.hxx>
32 : #include <svtools/miscopt.hxx>
33 : #include <toolkit/helper/vclunohelper.hxx>
34 : #include <vcl/toolbox.hxx>
35 : #include <comphelper/processfactory.hxx>
36 :
37 : const int TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIBLE = 1;
38 : const char TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIBLE[] = "SupportsVisible";
39 :
40 :
41 : using namespace ::cppu;
42 : using namespace ::com::sun::star::awt;
43 : using namespace ::com::sun::star::uno;
44 : using namespace ::com::sun::star::util;
45 : using namespace ::com::sun::star::beans;
46 : using namespace ::com::sun::star::lang;
47 : using namespace ::com::sun::star::frame;
48 :
49 : namespace svt
50 : {
51 :
52 132320 : ToolboxController::ToolboxController(
53 : const Reference< XComponentContext >& rxContext,
54 : const Reference< XFrame >& xFrame,
55 : const OUString& aCommandURL ) :
56 132320 : OPropertyContainer( GetBroadcastHelper() )
57 : , m_bSupportVisible( false )
58 : , m_bInitialized( false )
59 : , m_bDisposed( false )
60 : , m_nToolBoxId( SAL_MAX_UINT16 )
61 : , m_xFrame( xFrame )
62 : , m_xContext( rxContext )
63 : , m_aCommandURL( aCommandURL )
64 264640 : , m_aListenerContainer( m_aMutex )
65 : {
66 : OSL_ASSERT( m_xContext.is() );
67 : registerProperty( OUString(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIBLE),
68 : TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIBLE,
69 : css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY,
70 132320 : &m_bSupportVisible, getCppuType(&m_bSupportVisible));
71 :
72 : try
73 : {
74 132320 : m_xUrlTransformer = URLTransformer::create( rxContext );
75 : }
76 0 : catch(const Exception&)
77 : {
78 : }
79 132320 : }
80 :
81 30184 : ToolboxController::ToolboxController() :
82 30184 : OPropertyContainer(GetBroadcastHelper())
83 : , m_bSupportVisible(false)
84 : , m_bInitialized( false )
85 : , m_bDisposed( false )
86 : , m_nToolBoxId( SAL_MAX_UINT16 )
87 60368 : , m_aListenerContainer( m_aMutex )
88 : {
89 : registerProperty( OUString(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIBLE),
90 : TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIBLE,
91 : css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY,
92 30184 : &m_bSupportVisible, getCppuType(&m_bSupportVisible));
93 30184 : }
94 :
95 162484 : ToolboxController::~ToolboxController()
96 : {
97 162484 : }
98 :
99 84388 : Reference< XFrame > ToolboxController::getFrameInterface() const
100 : {
101 84388 : SolarMutexGuard aSolarMutexGuard;
102 84388 : return m_xFrame;
103 : }
104 :
105 0 : const Reference< XComponentContext > & ToolboxController::getContext() const
106 : {
107 0 : SolarMutexGuard aSolarMutexGuard;
108 0 : return m_xContext;
109 : }
110 :
111 1160 : Reference< XLayoutManager > ToolboxController::getLayoutManager() const
112 : {
113 1160 : Reference< XLayoutManager > xLayoutManager;
114 2320 : Reference< XPropertySet > xPropSet;
115 : {
116 1160 : SolarMutexGuard aSolarMutexGuard;
117 1160 : xPropSet = Reference< XPropertySet >( m_xFrame, UNO_QUERY );
118 : }
119 :
120 1160 : if ( xPropSet.is() )
121 : {
122 : try
123 : {
124 1160 : xLayoutManager.set(xPropSet->getPropertyValue("LayoutManager"),UNO_QUERY);
125 : }
126 0 : catch ( Exception& )
127 : {
128 : }
129 : }
130 :
131 2320 : return xLayoutManager;
132 : }
133 :
134 : // XInterface
135 1358308 : Any SAL_CALL ToolboxController::queryInterface( const Type& rType )
136 : throw ( RuntimeException, std::exception )
137 : {
138 1358308 : css::uno::Any a(ToolboxController_Base::queryInterface(rType));
139 1358308 : return a.hasValue() ? a : OPropertyContainer::queryInterface(rType);
140 : }
141 :
142 3560723 : void SAL_CALL ToolboxController::acquire() throw ()
143 : {
144 3560723 : ToolboxController_Base::acquire();
145 3560723 : }
146 :
147 3560703 : void SAL_CALL ToolboxController::release() throw ()
148 : {
149 3560703 : ToolboxController_Base::release();
150 3560703 : }
151 :
152 0 : css::uno::Sequence<css::uno::Type> ToolboxController::getTypes()
153 : throw (css::uno::RuntimeException, std::exception)
154 : {
155 0 : css::uno::Sequence<css::uno::Type> s1(ToolboxController_Base::getTypes());
156 0 : css::uno::Sequence<css::uno::Type> s2(getBaseTypes());
157 0 : sal_Int32 n = s1.getLength();
158 0 : s1.realloc(n + s2.getLength());
159 0 : for (sal_Int32 i = 0; i != s2.getLength(); ++i) {
160 0 : s1[n + i] = s2[i];
161 : }
162 0 : return s1;
163 : }
164 :
165 163236 : void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments )
166 : throw ( Exception, RuntimeException, std::exception )
167 : {
168 163236 : bool bInitialized( true );
169 :
170 : {
171 163236 : SolarMutexGuard aSolarMutexGuard;
172 :
173 163236 : if ( m_bDisposed )
174 0 : throw DisposedException();
175 :
176 163236 : bInitialized = m_bInitialized;
177 : }
178 :
179 163236 : if ( !bInitialized )
180 : {
181 147734 : SolarMutexGuard aSolarMutexGuard;
182 147734 : m_bInitialized = true;
183 147734 : m_bSupportVisible = false;
184 295468 : PropertyValue aPropValue;
185 876722 : for ( int i = 0; i < aArguments.getLength(); i++ )
186 : {
187 728988 : if ( aArguments[i] >>= aPropValue )
188 : {
189 728988 : if ( aPropValue.Name == "Frame" )
190 147734 : m_xFrame.set(aPropValue.Value,UNO_QUERY);
191 581254 : else if ( aPropValue.Name == "CommandURL" )
192 147734 : aPropValue.Value >>= m_aCommandURL;
193 433520 : else if ( aPropValue.Name == "ServiceManager" )
194 : {
195 147734 : Reference<XMultiServiceFactory> xMSF(aPropValue.Value, UNO_QUERY);
196 147734 : if (xMSF.is())
197 147734 : m_xContext = comphelper::getComponentContext(xMSF);
198 : }
199 285786 : else if ( aPropValue.Name == "ParentWindow" )
200 95508 : m_xParentWindow.set(aPropValue.Value,UNO_QUERY);
201 190278 : else if ( aPropValue.Name == "ModuleIdentifier" )
202 95508 : aPropValue.Value >>= m_sModuleName;
203 94770 : else if ( aPropValue.Name == "Identifier" )
204 94770 : aPropValue.Value >>= m_nToolBoxId;
205 : }
206 : }
207 :
208 : try
209 : {
210 147734 : if ( !m_xUrlTransformer.is() && m_xContext.is() )
211 30184 : m_xUrlTransformer = URLTransformer::create( m_xContext );
212 : }
213 0 : catch(const Exception&)
214 : {
215 : }
216 :
217 147734 : if ( !m_aCommandURL.isEmpty() )
218 295468 : m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() ));
219 : }
220 163236 : }
221 :
222 139506 : void SAL_CALL ToolboxController::update()
223 : throw ( RuntimeException, std::exception )
224 : {
225 : {
226 139506 : SolarMutexGuard aSolarMutexGuard;
227 139506 : if ( m_bDisposed )
228 0 : throw DisposedException();
229 : }
230 :
231 : // Bind all registered listeners to their dispatch objects
232 139506 : bindListener();
233 139506 : }
234 :
235 : // XComponent
236 162280 : void SAL_CALL ToolboxController::dispose()
237 : throw (::com::sun::star::uno::RuntimeException, std::exception)
238 : {
239 162280 : Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
240 :
241 : {
242 162280 : SolarMutexGuard aSolarMutexGuard;
243 162280 : if ( m_bDisposed )
244 0 : throw DisposedException();
245 : }
246 :
247 324560 : com::sun::star::lang::EventObject aEvent( xThis );
248 162280 : m_aListenerContainer.disposeAndClear( aEvent );
249 :
250 324560 : SolarMutexGuard aSolarMutexGuard;
251 324560 : Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
252 162280 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
253 499758 : while ( pIter != m_aListenerMap.end() )
254 : {
255 : try
256 : {
257 175198 : Reference< XDispatch > xDispatch( pIter->second );
258 :
259 350396 : com::sun::star::util::URL aTargetURL;
260 175198 : aTargetURL.Complete = pIter->first;
261 175198 : if ( m_xUrlTransformer.is() )
262 175198 : m_xUrlTransformer->parseStrict( aTargetURL );
263 :
264 175198 : if ( xDispatch.is() && xStatusListener.is() )
265 285977 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
266 : }
267 0 : catch ( Exception& )
268 : {
269 : }
270 :
271 175198 : ++pIter;
272 : }
273 :
274 324560 : m_bDisposed = true;
275 162280 : }
276 :
277 0 : void SAL_CALL ToolboxController::addEventListener( const Reference< XEventListener >& xListener )
278 : throw ( RuntimeException, std::exception )
279 : {
280 0 : m_aListenerContainer.addInterface( cppu::UnoType<XEventListener>::get(), xListener );
281 0 : }
282 :
283 0 : void SAL_CALL ToolboxController::removeEventListener( const Reference< XEventListener >& aListener )
284 : throw ( RuntimeException, std::exception )
285 : {
286 0 : m_aListenerContainer.removeInterface( cppu::UnoType<XEventListener>::get(), aListener );
287 0 : }
288 :
289 : // XEventListener
290 0 : void SAL_CALL ToolboxController::disposing( const EventObject& Source )
291 : throw ( RuntimeException, std::exception )
292 : {
293 0 : Reference< XInterface > xSource( Source.Source );
294 :
295 0 : SolarMutexGuard aSolarMutexGuard;
296 :
297 0 : if ( m_bDisposed )
298 0 : return;
299 :
300 0 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
301 0 : while ( pIter != m_aListenerMap.end() )
302 : {
303 : // Compare references and release dispatch references if they are equal.
304 0 : Reference< XInterface > xIfac( pIter->second, UNO_QUERY );
305 0 : if ( xSource == xIfac )
306 0 : pIter->second.clear();
307 0 : ++pIter;
308 0 : }
309 :
310 0 : Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
311 0 : if ( xIfac == xSource )
312 0 : m_xFrame.clear();
313 : }
314 :
315 : // XStatusListener
316 188 : void SAL_CALL ToolboxController::statusChanged( const FeatureStateEvent& )
317 : throw ( RuntimeException, std::exception )
318 : {
319 : // must be implemented by sub class
320 188 : }
321 :
322 : // XToolbarController
323 0 : void SAL_CALL ToolboxController::execute( sal_Int16 KeyModifier )
324 : throw (::com::sun::star::uno::RuntimeException, std::exception)
325 : {
326 0 : Reference< XDispatch > xDispatch;
327 0 : OUString aCommandURL;
328 :
329 : {
330 0 : SolarMutexGuard aSolarMutexGuard;
331 :
332 0 : if ( m_bDisposed )
333 0 : throw DisposedException();
334 :
335 0 : if ( m_bInitialized &&
336 0 : m_xFrame.is() &&
337 0 : m_xContext.is() &&
338 0 : !m_aCommandURL.isEmpty() )
339 : {
340 :
341 0 : aCommandURL = m_aCommandURL;
342 0 : URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
343 0 : if ( pIter != m_aListenerMap.end() )
344 0 : xDispatch = pIter->second;
345 0 : }
346 : }
347 :
348 0 : if ( xDispatch.is() )
349 : {
350 : try
351 : {
352 0 : com::sun::star::util::URL aTargetURL;
353 0 : Sequence<PropertyValue> aArgs( 1 );
354 :
355 : // Provide key modifier information to dispatch function
356 0 : aArgs[0].Name = "KeyModifier";
357 0 : aArgs[0].Value = makeAny( KeyModifier );
358 :
359 0 : aTargetURL.Complete = aCommandURL;
360 0 : if ( m_xUrlTransformer.is() )
361 0 : m_xUrlTransformer->parseStrict( aTargetURL );
362 0 : xDispatch->dispatch( aTargetURL, aArgs );
363 : }
364 0 : catch ( DisposedException& )
365 : {
366 : }
367 0 : }
368 0 : }
369 :
370 4 : void SAL_CALL ToolboxController::click()
371 : throw (::com::sun::star::uno::RuntimeException, std::exception)
372 : {
373 4 : }
374 :
375 0 : void SAL_CALL ToolboxController::doubleClick()
376 : throw (::com::sun::star::uno::RuntimeException, std::exception)
377 : {
378 0 : }
379 :
380 0 : Reference< XWindow > SAL_CALL ToolboxController::createPopupWindow()
381 : throw (::com::sun::star::uno::RuntimeException, std::exception)
382 : {
383 0 : return Reference< XWindow >();
384 : }
385 :
386 132300 : Reference< XWindow > SAL_CALL ToolboxController::createItemWindow( const Reference< XWindow >& )
387 : throw (::com::sun::star::uno::RuntimeException, std::exception)
388 : {
389 132300 : return Reference< XWindow >();
390 : }
391 :
392 16776 : void ToolboxController::addStatusListener( const OUString& aCommandURL )
393 : {
394 16776 : Reference< XDispatch > xDispatch;
395 16790 : Reference< XStatusListener > xStatusListener;
396 16790 : com::sun::star::util::URL aTargetURL;
397 :
398 : {
399 16776 : SolarMutexGuard aSolarMutexGuard;
400 16776 : URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
401 :
402 : // Already in the list of status listener. Do nothing.
403 16776 : if ( pIter != m_aListenerMap.end() )
404 254 : return;
405 :
406 : // Check if we are already initialized. Implementation starts adding itself as status listener when
407 : // intialize is called.
408 16522 : if ( !m_bInitialized )
409 : {
410 : // Put into the boost::unordered_map of status listener. Will be activated when initialized is called
411 16508 : m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() ));
412 16508 : return;
413 : }
414 : else
415 : {
416 : // Add status listener directly as intialize has already been called.
417 14 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
418 14 : if ( m_xContext.is() && xDispatchProvider.is() )
419 : {
420 14 : aTargetURL.Complete = aCommandURL;
421 14 : if ( m_xUrlTransformer.is() )
422 14 : m_xUrlTransformer->parseStrict( aTargetURL );
423 14 : xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
424 :
425 14 : xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
426 14 : URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL );
427 14 : if ( aIter != m_aListenerMap.end() )
428 : {
429 0 : Reference< XDispatch > xOldDispatch( aIter->second );
430 0 : aIter->second = xDispatch;
431 :
432 : try
433 : {
434 0 : if ( xOldDispatch.is() )
435 0 : xOldDispatch->removeStatusListener( xStatusListener, aTargetURL );
436 : }
437 0 : catch ( Exception& )
438 : {
439 0 : }
440 : }
441 : else
442 14 : m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch ));
443 14 : }
444 14 : }
445 : }
446 :
447 : // Call without locked mutex as we are called back from dispatch implementation
448 : try
449 : {
450 14 : if ( xDispatch.is() )
451 14 : xDispatch->addStatusListener( xStatusListener, aTargetURL );
452 : }
453 0 : catch ( Exception& )
454 : {
455 14 : }
456 : }
457 :
458 48 : void ToolboxController::removeStatusListener( const OUString& aCommandURL )
459 : {
460 48 : SolarMutexGuard aSolarMutexGuard;
461 :
462 48 : URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL );
463 48 : if ( pIter != m_aListenerMap.end() )
464 : {
465 48 : Reference< XDispatch > xDispatch( pIter->second );
466 96 : Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
467 48 : m_aListenerMap.erase( pIter );
468 :
469 : try
470 : {
471 48 : com::sun::star::util::URL aTargetURL;
472 48 : aTargetURL.Complete = aCommandURL;
473 48 : if ( m_xUrlTransformer.is() )
474 48 : m_xUrlTransformer->parseStrict( aTargetURL );
475 :
476 48 : if ( xDispatch.is() && xStatusListener.is() )
477 26 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
478 : }
479 0 : catch ( Exception& )
480 : {
481 48 : }
482 48 : }
483 48 : }
484 :
485 141068 : void ToolboxController::bindListener()
486 : {
487 141068 : std::vector< Listener > aDispatchVector;
488 282132 : Reference< XStatusListener > xStatusListener;
489 :
490 : {
491 141068 : SolarMutexGuard aSolarMutexGuard;
492 :
493 141068 : if ( !m_bInitialized )
494 141072 : return;
495 :
496 : // Collect all registered command URL's and store them temporary
497 282128 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
498 141064 : if ( m_xContext.is() && xDispatchProvider.is() )
499 : {
500 141064 : xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
501 141064 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
502 435913 : while ( pIter != m_aListenerMap.end() )
503 : {
504 153785 : com::sun::star::util::URL aTargetURL;
505 153785 : aTargetURL.Complete = pIter->first;
506 153785 : if ( m_xUrlTransformer.is() )
507 153785 : m_xUrlTransformer->parseStrict( aTargetURL );
508 :
509 307570 : Reference< XDispatch > xDispatch( pIter->second );
510 153785 : if ( xDispatch.is() )
511 : {
512 : // We already have a dispatch object => we have to requery.
513 : // Release old dispatch object and remove it as listener
514 : try
515 : {
516 4498 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
517 : }
518 0 : catch ( Exception& )
519 : {
520 : }
521 : }
522 :
523 153785 : pIter->second.clear();
524 153785 : xDispatch.clear();
525 :
526 : // Query for dispatch object. Old dispatch will be released with this, too.
527 : try
528 : {
529 153785 : xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
530 : }
531 0 : catch ( Exception& )
532 : {
533 : }
534 153785 : pIter->second = xDispatch;
535 :
536 307570 : Listener aListener( aTargetURL, xDispatch );
537 153785 : aDispatchVector.push_back( aListener );
538 153785 : ++pIter;
539 153785 : }
540 141064 : }
541 : }
542 :
543 : // Call without locked mutex as we are called back from dispatch implementation
544 141064 : if ( xStatusListener.is() )
545 : {
546 : try
547 : {
548 294849 : for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ )
549 : {
550 153785 : Listener& rListener = aDispatchVector[i];
551 153785 : if ( rListener.xDispatch.is() )
552 115309 : rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL );
553 38476 : else if ( rListener.aURL.Complete == m_aCommandURL )
554 : {
555 : try
556 : {
557 : // Send status changed for the main URL, if we cannot get a valid dispatch object.
558 : // UI disables the button. Catch exception as we release our mutex, it is possible
559 : // that someone else already disposed this instance!
560 38476 : FeatureStateEvent aFeatureStateEvent;
561 38476 : aFeatureStateEvent.IsEnabled = sal_False;
562 38476 : aFeatureStateEvent.FeatureURL = rListener.aURL;
563 38476 : aFeatureStateEvent.State = Any();
564 38476 : xStatusListener->statusChanged( aFeatureStateEvent );
565 : }
566 0 : catch ( Exception& )
567 : {
568 : }
569 : }
570 : }
571 : }
572 0 : catch ( Exception& )
573 : {
574 : }
575 141064 : }
576 : }
577 :
578 0 : void ToolboxController::unbindListener()
579 : {
580 0 : SolarMutexGuard aSolarMutexGuard;
581 :
582 0 : if ( !m_bInitialized )
583 0 : return;
584 :
585 : // Collect all registered command URL's and store them temporary
586 0 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
587 0 : if ( m_xContext.is() && xDispatchProvider.is() )
588 : {
589 0 : Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
590 0 : URLToDispatchMap::iterator pIter = m_aListenerMap.begin();
591 0 : while ( pIter != m_aListenerMap.end() )
592 : {
593 0 : com::sun::star::util::URL aTargetURL;
594 0 : aTargetURL.Complete = pIter->first;
595 0 : if ( m_xUrlTransformer.is() )
596 0 : m_xUrlTransformer->parseStrict( aTargetURL );
597 :
598 0 : Reference< XDispatch > xDispatch( pIter->second );
599 0 : if ( xDispatch.is() )
600 : {
601 : // We already have a dispatch object => we have to requery.
602 : // Release old dispatch object and remove it as listener
603 : try
604 : {
605 0 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
606 : }
607 0 : catch ( Exception& )
608 : {
609 : }
610 : }
611 0 : pIter->second.clear();
612 0 : ++pIter;
613 0 : }
614 0 : }
615 : }
616 :
617 1696 : bool ToolboxController::isBound() const
618 : {
619 1696 : SolarMutexGuard aSolarMutexGuard;
620 :
621 1696 : if ( !m_bInitialized )
622 0 : return false;
623 :
624 1696 : URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL );
625 1696 : if ( pIter != m_aListenerMap.end() )
626 1696 : return pIter->second.is();
627 :
628 0 : return false;
629 : }
630 :
631 0 : void ToolboxController::updateStatus()
632 : {
633 0 : bindListener();
634 0 : }
635 :
636 0 : void ToolboxController::updateStatus( const OUString& aCommandURL )
637 : {
638 0 : Reference< XDispatch > xDispatch;
639 0 : Reference< XStatusListener > xStatusListener;
640 0 : com::sun::star::util::URL aTargetURL;
641 :
642 : {
643 0 : SolarMutexGuard aSolarMutexGuard;
644 :
645 0 : if ( !m_bInitialized )
646 0 : return;
647 :
648 : // Try to find a dispatch object for the requested command URL
649 0 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
650 0 : xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY );
651 0 : if ( m_xContext.is() && xDispatchProvider.is() )
652 : {
653 0 : aTargetURL.Complete = aCommandURL;
654 0 : if ( m_xUrlTransformer.is() )
655 0 : m_xUrlTransformer->parseStrict( aTargetURL );
656 0 : xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
657 0 : }
658 : }
659 :
660 0 : if ( xDispatch.is() && xStatusListener.is() )
661 : {
662 : // Catch exception as we release our mutex, it is possible that someone else
663 : // has already disposed this instance!
664 : // Add/remove status listener to get a update status information from the
665 : // requested command.
666 : try
667 : {
668 0 : xDispatch->addStatusListener( xStatusListener, aTargetURL );
669 0 : xDispatch->removeStatusListener( xStatusListener, aTargetURL );
670 : }
671 0 : catch ( Exception& )
672 : {
673 : }
674 0 : }
675 : }
676 :
677 :
678 :
679 0 : void ToolboxController::dispatchCommand( const OUString& sCommandURL, const Sequence< PropertyValue >& rArgs, const OUString &sTarget )
680 : {
681 : try
682 : {
683 0 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
684 0 : URL aURL;
685 0 : aURL.Complete = sCommandURL;
686 0 : getURLTransformer()->parseStrict( aURL );
687 :
688 0 : Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, sTarget, 0 ), UNO_QUERY_THROW );
689 :
690 0 : DispatchInfo *pDispatchInfo = new DispatchInfo( xDispatch, aURL, rArgs );
691 0 : if ( !Application::PostUserEvent( STATIC_LINK(0, ToolboxController, ExecuteHdl_Impl),
692 0 : pDispatchInfo ) )
693 0 : delete pDispatchInfo;
694 :
695 : }
696 0 : catch( Exception& )
697 : {
698 : }
699 0 : }
700 :
701 :
702 :
703 0 : com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL ToolboxController::getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException, std::exception)
704 : {
705 0 : Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
706 0 : return xInfo;
707 : }
708 :
709 189144 : ::cppu::IPropertyArrayHelper& ToolboxController::getInfoHelper()
710 : {
711 189144 : return *const_cast<ToolboxController*>(this)->getArrayHelper();
712 : }
713 :
714 :
715 1295 : ::cppu::IPropertyArrayHelper* ToolboxController::createArrayHelper( ) const
716 : {
717 1295 : com::sun::star::uno::Sequence< Property > aProps;
718 1295 : describeProperties(aProps);
719 1295 : return new ::cppu::OPropertyArrayHelper(aProps);
720 : }
721 :
722 2432 : void ToolboxController::setSupportVisibleProperty(bool bValue)
723 : {
724 2432 : m_bSupportVisible = bValue;
725 2432 : }
726 :
727 0 : sal_Bool SAL_CALL ToolboxController::convertFastPropertyValue( com::sun::star::uno::Any& aConvertedValue ,
728 : com::sun::star::uno::Any& aOldValue ,
729 : sal_Int32 nHandle ,
730 : const com::sun::star::uno::Any& aValue ) throw( com::sun::star::lang::IllegalArgumentException )
731 : {
732 0 : switch (nHandle)
733 : {
734 : case TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIBLE:
735 : {
736 0 : bool aNewValue(false);
737 0 : aValue >>= aNewValue;
738 0 : if (aNewValue != m_bSupportVisible)
739 : {
740 0 : aConvertedValue <<= aNewValue;
741 0 : aOldValue <<= m_bSupportVisible;
742 0 : return sal_True;
743 : }
744 0 : return sal_False;
745 : }
746 : }
747 0 : return OPropertyContainer::convertFastPropertyValue(aConvertedValue, aOldValue, nHandle, aValue);
748 : }
749 :
750 2432 : void SAL_CALL ToolboxController::setFastPropertyValue_NoBroadcast(
751 : sal_Int32 nHandle,
752 : const com::sun::star::uno::Any& aValue )
753 : throw( com::sun::star::uno::Exception, std::exception)
754 : {
755 2432 : OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, aValue);
756 2432 : if (TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIBLE == nHandle)
757 : {
758 2432 : bool rValue(false);
759 2432 : if (( aValue >>= rValue ) && m_bInitialized)
760 2432 : this->setSupportVisibleProperty( rValue );
761 : }
762 2432 : }
763 :
764 :
765 :
766 0 : IMPL_STATIC_LINK_NOINSTANCE( ToolboxController, ExecuteHdl_Impl, DispatchInfo*, pDispatchInfo )
767 : {
768 0 : pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
769 0 : delete pDispatchInfo;
770 0 : return 0;
771 : }
772 :
773 1557 : void ToolboxController::enable( bool bEnable )
774 : {
775 1557 : ToolBox* pToolBox = 0;
776 1557 : sal_uInt16 nItemId = 0;
777 1557 : if( getToolboxId( nItemId, &pToolBox ) )
778 : {
779 1557 : pToolBox->EnableItem( nItemId, bEnable ? sal_True : sal_False );
780 : }
781 1557 : }
782 :
783 1605 : bool ToolboxController::getToolboxId( sal_uInt16& rItemId, ToolBox** ppToolBox )
784 : {
785 1605 : if( (m_nToolBoxId != SAL_MAX_UINT16) && (ppToolBox == 0) )
786 0 : return m_nToolBoxId;
787 :
788 1605 : ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
789 :
790 1605 : if( (m_nToolBoxId == SAL_MAX_UINT16) && pToolBox )
791 : {
792 0 : const sal_uInt16 nCount = pToolBox->GetItemCount();
793 0 : for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
794 : {
795 0 : const sal_uInt16 nItemId = pToolBox->GetItemId( nPos );
796 0 : if ( pToolBox->GetItemCommand( nItemId ) == m_aCommandURL )
797 : {
798 0 : m_nToolBoxId = nItemId;
799 0 : break;
800 : }
801 : }
802 : }
803 :
804 1605 : if( ppToolBox )
805 1605 : *ppToolBox = pToolBox;
806 :
807 1605 : rItemId = m_nToolBoxId;
808 :
809 1605 : return (rItemId != SAL_MAX_UINT16) && (( ppToolBox == 0) || (*ppToolBox != 0) );
810 : }
811 : //end
812 :
813 1227 : } // svt
814 :
815 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|