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