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