update credits
[LibreOffice.git] / accessibility / source / standard / vclxaccessibletoolbox.cxx
blob205c08b6696e680e3949e1fb35284c53a018a1aa
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <string.h>
21 #include <accessibility/standard/vclxaccessibletoolbox.hxx>
22 #include <accessibility/standard/vclxaccessibletoolboxitem.hxx>
23 #include <toolkit/helper/convert.hxx>
25 #include <unotools/accessiblestatesethelper.hxx>
26 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/lang/XUnoTunnel.hpp>
29 #include <vcl/toolbox.hxx>
30 #include <comphelper/accessiblewrapper.hxx>
31 #include <comphelper/processfactory.hxx>
33 using namespace ::comphelper;
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::accessibility;
39 namespace
41 // =========================================================================
42 // = OToolBoxWindowItemContext
43 // =========================================================================
44 /** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window
46 class OToolBoxWindowItemContext : public OAccessibleContextWrapper
48 sal_Int32 m_nIndexInParent;
49 public:
50 OToolBoxWindowItemContext(sal_Int32 _nIndexInParent,
51 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
52 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
53 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible,
54 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
55 ) : OAccessibleContextWrapper(
56 _rxContext,
57 _rxInnerAccessibleContext,
58 _rxOwningAccessible,
59 _rxParentAccessible )
60 ,m_nIndexInParent(_nIndexInParent)
63 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
66 // -------------------------------------------------------------------------
67 sal_Int32 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException)
69 ::osl::MutexGuard aGuard( m_aMutex );
70 return m_nIndexInParent;
73 // =========================================================================
74 // = OToolBoxWindowItem
75 // =========================================================================
76 typedef ::cppu::ImplHelper1 < XUnoTunnel
77 > OToolBoxWindowItem_Base;
79 /** XAccessible implementation for a toolbox item which is represented by a VCL Window
81 class OToolBoxWindowItem
82 :public OAccessibleWrapper
83 ,public OToolBoxWindowItem_Base
85 private:
86 sal_Int32 m_nIndexInParent;
88 public:
89 inline sal_Int32 getIndexInParent() const { return m_nIndexInParent; }
90 inline void setIndexInParent( sal_Int32 _nNewIndex ) { m_nIndexInParent = _nNewIndex; }
92 static sal_Bool isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation = NULL );
94 public:
95 OToolBoxWindowItem(sal_Int32 _nIndexInParent,
96 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
97 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxInnerAccessible,
98 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
99 ) : OAccessibleWrapper(
100 _rxContext,
101 _rxInnerAccessible,
102 _rxParentAccessible)
103 ,m_nIndexInParent(_nIndexInParent)
107 protected:
108 // XInterface
109 DECLARE_XINTERFACE( )
110 DECLARE_XTYPEPROVIDER( )
112 // OAccessibleWrapper
113 virtual OAccessibleContextWrapper* createAccessibleContext(
114 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerContext
117 // XUnoTunnel
118 virtual sal_Int64 SAL_CALL getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw (RuntimeException);
119 static Sequence< sal_Int8 > getUnoTunnelImplementationId();
122 // -------------------------------------------------------------------------
123 IMPLEMENT_FORWARD_XINTERFACE2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
124 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
126 // -------------------------------------------------------------------------
127 OAccessibleContextWrapper* OToolBoxWindowItem::createAccessibleContext(
128 const Reference< XAccessibleContext >& _rxInnerContext )
130 return new OToolBoxWindowItemContext( m_nIndexInParent, getComponentContext(), _rxInnerContext, this, getParent() );
133 //--------------------------------------------------------------------
134 sal_Bool OToolBoxWindowItem::isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation )
136 OToolBoxWindowItem* pImplementation = NULL;
138 Reference< XUnoTunnel > xTunnel( _rxAcc, UNO_QUERY );
139 if ( xTunnel.is() )
140 pImplementation = reinterpret_cast< OToolBoxWindowItem* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
142 if ( _ppImplementation )
143 *_ppImplementation = pImplementation;
145 return NULL != pImplementation;
148 //--------------------------------------------------------------------
149 Sequence< sal_Int8 > OToolBoxWindowItem::getUnoTunnelImplementationId()
151 static ::cppu::OImplementationId * pId = 0;
152 if (! pId)
154 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
155 if (! pId)
157 static ::cppu::OImplementationId aId;
158 pId = &aId;
161 return pId->getImplementationId();
164 //--------------------------------------------------------------------
165 sal_Int64 SAL_CALL OToolBoxWindowItem::getSomething( const Sequence< sal_Int8 >& _rId ) throw (RuntimeException)
167 if ( ( 16 == _rId.getLength() )
168 && ( 0 == memcmp( getUnoTunnelImplementationId().getConstArray(), _rId.getConstArray(), 16 ) )
170 return reinterpret_cast< sal_Int64>( this );
172 return 0;
176 // -----------------------------------------------------------------------------
177 // VCLXAccessibleToolBox
178 // -----------------------------------------------------------------------------
179 VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ) :
181 VCLXAccessibleComponent( pVCLXWindow )
185 // -----------------------------------------------------------------------------
186 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
189 // -----------------------------------------------------------------------------
190 VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( sal_Int32 _nPos, bool _bMustHaveFocus )
192 VCLXAccessibleToolBoxItem* pItem = NULL;
193 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
194 if ( pToolBox && ( !_bMustHaveFocus || pToolBox->HasFocus() ) )
196 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
197 // returns only toolbox buttons, not windows
198 if ( aIter != m_aAccessibleChildren.end() && !aIter->second.is())
199 pItem = static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
202 return pItem;
204 // -----------------------------------------------------------------------------
206 void VCLXAccessibleToolBox::UpdateFocus_Impl()
208 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
209 if( !pToolBox )
210 return;
212 // submit events only if toolbox has the focus to avoid sending events due to mouse move
213 sal_Bool bHasFocus = sal_False;
214 if ( pToolBox->HasFocus() )
215 bHasFocus = sal_True;
216 else
218 // check for subtoolbar, i.e. check if our parent is a toolbar
219 ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
220 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
221 if ( pToolBoxParent && pToolBoxParent->HasFocus() )
222 bHasFocus = sal_True;
225 if ( bHasFocus )
227 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
228 sal_uInt16 nFocusCount = 0;
229 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
230 aIter != m_aAccessibleChildren.end(); ++aIter )
232 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)aIter->first );
234 if ( aIter->second.is() )
236 VCLXAccessibleToolBoxItem* pItem =
237 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
238 if ( pItem->HasFocus() && nItemId != nHighlightItemId )
240 // reset the old focused item
241 pItem->SetFocus( sal_False );
242 nFocusCount++;
244 if ( nItemId == nHighlightItemId )
246 // set the new focused item
247 pItem->SetFocus( sal_True );
248 nFocusCount++;
251 // both items changed?
252 if ( nFocusCount > 1 )
253 break;
257 // -----------------------------------------------------------------------------
258 void VCLXAccessibleToolBox::ReleaseFocus_Impl( sal_Int32 _nPos )
260 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
261 if ( pToolBox ) // #107124#, do not check for focus because this message is also handled in losefocus
263 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
264 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
266 VCLXAccessibleToolBoxItem* pItem =
267 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
268 if ( pItem->HasFocus() )
269 pItem->SetFocus( sal_False );
273 // -----------------------------------------------------------------------------
274 void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 )
276 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
277 if ( pToolBox )
279 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
280 aIter != m_aAccessibleChildren.end(); ++aIter )
282 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)aIter->first );
284 VCLXAccessibleToolBoxItem* pItem =
285 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
286 pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) );
290 // -----------------------------------------------------------------------------
291 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( sal_Int32 _nPos )
293 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
294 if ( pToolBox )
296 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)_nPos );
298 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
299 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
301 VCLXAccessibleToolBoxItem* pItem =
302 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
303 if ( pItem )
304 pItem->SetIndeterminate( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW );
308 // -----------------------------------------------------------------------------
309 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator& _rMapPos,
310 bool _bNotifyRemoval, bool _bDispose )
312 Reference< XAccessible > xItemAcc( _rMapPos->second );
313 if ( !xItemAcc.is() )
314 return;
316 if ( _bNotifyRemoval )
318 NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( xItemAcc ), Any() );
321 OToolBoxWindowItem* pWindowItem = NULL;
322 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
324 static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() )->ReleaseToolBox();
325 if ( _bDispose )
326 ::comphelper::disposeComponent( xItemAcc );
328 else
330 if ( _bDispose )
332 if ( pWindowItem )
334 Reference< XAccessibleContext > xContext( pWindowItem->getContextNoCreate() );
335 ::comphelper::disposeComponent( xContext );
341 // -----------------------------------------------------------------------------
342 void VCLXAccessibleToolBox::UpdateItem_Impl( sal_Int32 _nPos, sal_Bool _bItemAdded )
344 if ( _nPos < sal_Int32( m_aAccessibleChildren.size() ) )
346 UpdateAllItems_Impl();
347 return;
350 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
351 if ( pToolBox )
353 if ( !_bItemAdded )
354 { // the item was removed
355 // -> destroy the old item
356 ToolBoxItemsMap::iterator aItemPos = m_aAccessibleChildren.find( _nPos );
357 if ( m_aAccessibleChildren.end() != aItemPos )
359 implReleaseToolboxItem( aItemPos, true, true );
360 m_aAccessibleChildren.erase( aItemPos );
364 // adjust the "index-in-parent"s
365 ToolBoxItemsMap::iterator aIndexAdjust = m_aAccessibleChildren.upper_bound( _nPos );
366 while ( m_aAccessibleChildren.end() != aIndexAdjust )
368 Reference< XAccessible > xItemAcc( aIndexAdjust->second );
370 OToolBoxWindowItem* pWindowItem = NULL;
371 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
373 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() );
374 if ( pItem )
376 sal_Int32 nIndex = pItem->getIndexInParent( );
377 nIndex += (_bItemAdded ? +1 : -1);
378 pItem->setIndexInParent( nIndex );
381 else
383 if ( pWindowItem )
385 sal_Int32 nIndex = pWindowItem->getIndexInParent( );
386 nIndex += (_bItemAdded ? +1 : -1);
387 pWindowItem->setIndexInParent( nIndex );
391 ++aIndexAdjust;
394 if ( _bItemAdded )
396 // TODO: we should make this dependent on the existence of event listeners
397 // with the current implementation, we always create accessible object
398 Any aNewChild = makeAny( getAccessibleChild( (sal_Int32)_nPos ) );
399 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewChild );
403 // -----------------------------------------------------------------------------
404 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
406 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
407 if ( pToolBox )
409 // deregister the old items
410 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
411 aIter != m_aAccessibleChildren.end(); ++aIter )
413 implReleaseToolboxItem( aIter, true, true );
415 m_aAccessibleChildren.clear();
417 // register the new items
418 sal_uInt16 i, nCount = pToolBox->GetItemCount();
419 for ( i = 0; i < nCount; ++i )
421 Any aNewValue;
422 aNewValue <<= getAccessibleChild( (sal_Int32)i );;
423 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
428 // -----------------------------------------------------------------------------
430 void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( Window* pWindow, bool bOpen )
432 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
433 if( pWindow && pToolBox )
435 Reference< XAccessible > xChild( pWindow->GetAccessible() );
436 if( xChild.is() )
438 Reference< XAccessible > xChildItem( getAccessibleChild( static_cast< sal_Int32 >( pToolBox->GetItemPos( pToolBox->GetDownItemId() ) ) ) );
439 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xChildItem.get() );
441 pItem->SetChild( xChild );
442 pItem->NotifyChildEvent( xChild, bOpen );
447 // -----------------------------------------------------------------------------
448 void VCLXAccessibleToolBox::UpdateItemName_Impl( sal_Int32 _nPos )
450 VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos, false );
451 if ( pItem )
452 pItem->NameChanged();
454 // -----------------------------------------------------------------------------
455 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( sal_Int32 _nPos )
457 VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos, false );
458 if ( pItem )
459 pItem->ToggleEnableState();
461 // -----------------------------------------------------------------------------
462 void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent& rVclWindowEvent, bool _bShow )
464 Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
465 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
466 if ( pChildWindow
467 && pToolBox
468 && pToolBox == pChildWindow->GetParent()
469 && pChildWindow->GetType() == WINDOW_TOOLBOX )
471 sal_Int32 nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
472 Reference< XAccessible > xItem = getAccessibleChild( nIndex );
473 if ( xItem.is() )
475 Reference< XAccessible > xChild = pChildWindow->GetAccessible();
476 VCLXAccessibleToolBoxItem* pItem =
477 static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
478 pItem->SetChild( xChild );
479 pItem->NotifyChildEvent( xChild, _bShow );
483 // -----------------------------------------------------------------------------
484 void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox* _pSubToolBox )
486 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
487 if ( pToolBox )
489 sal_Int32 nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
490 Reference< XAccessible > xItem = getAccessibleChild( nIndex );
491 if ( xItem.is() )
493 Reference< XAccessible > xChild = _pSubToolBox->GetAccessible();
494 VCLXAccessibleToolBoxItem* pItem =
495 static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
496 if ( pItem->GetChild() == xChild )
498 pItem->SetChild( Reference< XAccessible >() );
499 pItem->NotifyChildEvent( xChild, false );
504 // -----------------------------------------------------------------------------
505 void VCLXAccessibleToolBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
507 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
509 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
510 if ( pToolBox )
512 rStateSet.AddState( AccessibleStateType::FOCUSABLE );
513 if ( pToolBox->IsHorizontal() )
514 rStateSet.AddState( AccessibleStateType::HORIZONTAL );
515 else
516 rStateSet.AddState( AccessibleStateType::VERTICAL );
519 // -----------------------------------------------------------------------------
520 void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
522 // to prevent an early release of the toolbox (VCLEVENT_OBJECT_DYING)
523 Reference< XAccessibleContext > xTemp = this;
525 switch ( rVclWindowEvent.GetId() )
527 case VCLEVENT_TOOLBOX_CLICK:
529 if ( rVclWindowEvent.GetData() )
531 UpdateChecked_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
532 UpdateIndeterminate_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
534 break;
536 case VCLEVENT_TOOLBOX_DOUBLECLICK:
537 case VCLEVENT_TOOLBOX_ACTIVATE:
538 case VCLEVENT_TOOLBOX_DEACTIVATE:
539 case VCLEVENT_TOOLBOX_SELECT:
540 break;
542 case VCLEVENT_TOOLBOX_HIGHLIGHT:
543 UpdateFocus_Impl();
544 break;
546 case VCLEVENT_TOOLBOX_HIGHLIGHTOFF:
547 ReleaseFocus_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
548 break;
550 case VCLEVENT_TOOLBOX_ITEMADDED :
551 // UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), VCLEVENT_TOOLBOX_ITEMADDED == rVclWindowEvent.GetId() );
552 UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), sal_True );
553 break;
555 case VCLEVENT_TOOLBOX_ITEMREMOVED :
556 case VCLEVENT_TOOLBOX_ALLITEMSCHANGED :
558 UpdateAllItems_Impl();
559 break;
562 case VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED:
564 sal_Int32 nPos = (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData();
565 ToolBoxItemsMap::iterator aAccessiblePos( m_aAccessibleChildren.find( nPos ) );
566 if ( m_aAccessibleChildren.end() != aAccessiblePos )
568 implReleaseToolboxItem( aAccessiblePos, false, true );
569 m_aAccessibleChildren.erase (aAccessiblePos);
572 Any aNewValue;
573 aNewValue <<= getAccessibleChild(nPos);
574 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
575 break;
577 case VCLEVENT_TOOLBOX_ITEMTEXTCHANGED :
578 UpdateItemName_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
579 break;
581 case VCLEVENT_TOOLBOX_ITEMENABLED :
582 case VCLEVENT_TOOLBOX_ITEMDISABLED :
584 UpdateItemEnabled_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
585 break;
588 case VCLEVENT_DROPDOWN_OPEN:
589 case VCLEVENT_DROPDOWN_CLOSE:
591 UpdateCustomPopupItemp_Impl( static_cast< Window* >( rVclWindowEvent.GetData() ), rVclWindowEvent.GetId() == VCLEVENT_DROPDOWN_OPEN );
592 break;
595 case VCLEVENT_OBJECT_DYING :
597 // if this toolbox is a subtoolbox, we have to relese it from its parent
598 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
599 if ( pToolBox && pToolBox->GetParent() &&
600 pToolBox->GetParent()->GetType() == WINDOW_TOOLBOX )
602 VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >(
603 pToolBox->GetParent()->GetAccessible()->getAccessibleContext().get() );
604 if ( pParent )
605 pParent->ReleaseSubToolBox( pToolBox );
608 // dispose all items
609 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
610 aIter != m_aAccessibleChildren.end(); ++aIter )
612 implReleaseToolboxItem( aIter, false, true );
614 m_aAccessibleChildren.clear();
616 //!!! no break to call base class
619 default:
620 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
623 // -----------------------------------------------------------------------------
624 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
626 switch ( rVclWindowEvent.GetId() )
628 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
630 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
631 if ( xReturn.is() )
632 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny(xReturn) );
633 else
634 HandleSubToolBarEvent( rVclWindowEvent, true );
636 break;
638 default:
639 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
643 // -----------------------------------------------------------------------------
644 // XInterface
645 // -----------------------------------------------------------------------------
646 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
647 // -----------------------------------------------------------------------------
648 // XTypeProvider
649 // -----------------------------------------------------------------------------
650 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
651 // -----------------------------------------------------------------------------
652 // XComponent
653 // -----------------------------------------------------------------------------
654 void SAL_CALL VCLXAccessibleToolBox::disposing()
656 VCLXAccessibleComponent::disposing();
658 // release the items
659 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
660 aIter != m_aAccessibleChildren.end(); ++aIter )
662 implReleaseToolboxItem( aIter, false, true );
664 m_aAccessibleChildren.clear();
666 // -----------------------------------------------------------------------------
667 // XServiceInfo
668 // -----------------------------------------------------------------------------
669 OUString VCLXAccessibleToolBox::getImplementationName() throw (RuntimeException)
671 return OUString( "com.sun.star.comp.toolkit.AccessibleToolBox" );
673 // -----------------------------------------------------------------------------
674 Sequence< OUString > VCLXAccessibleToolBox::getSupportedServiceNames() throw (RuntimeException)
676 Sequence< OUString > aNames = VCLXAccessibleComponent::getSupportedServiceNames();
677 sal_Int32 nLength = aNames.getLength();
678 aNames.realloc( nLength + 1 );
679 aNames[nLength] = "com.sun.star.accessibility.AccessibleToolBox";
680 return aNames;
682 // -----------------------------------------------------------------------------
683 // XAccessibleContext
684 // -----------------------------------------------------------------------------
685 sal_Int32 SAL_CALL VCLXAccessibleToolBox::getAccessibleChildCount( ) throw (RuntimeException)
687 comphelper::OExternalLockGuard aGuard( this );
689 sal_Int32 nCount = 0;
690 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
691 if ( pToolBox )
692 nCount = pToolBox->GetItemCount();
694 return nCount;
696 // -----------------------------------------------------------------------------
697 Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
699 if ( i < 0 || i >= getAccessibleChildCount() )
700 throw IndexOutOfBoundsException();
702 comphelper::OExternalLockGuard aGuard( this );
704 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
705 if ( pToolBox )
707 Reference< XAccessible > xChild;
708 // search for the child
709 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find(i);
710 if ( m_aAccessibleChildren.end() == aIter )
712 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)i );
713 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
714 Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
715 // not found -> create a new child
716 VCLXAccessibleToolBoxItem* pChild = new VCLXAccessibleToolBoxItem( pToolBox, i );
717 Reference< XAccessible> xParent = pChild;
718 if ( pItemWindow )
720 xChild = new OToolBoxWindowItem(0,::comphelper::getProcessComponentContext(),pItemWindow->GetAccessible(),xParent);
721 pItemWindow->SetAccessible(xChild);
722 pChild->SetChild( xChild );
724 xChild = pChild;
725 if ( nHighlightItemId > 0 && nItemId == nHighlightItemId )
726 pChild->SetFocus( sal_True );
727 if ( pToolBox->IsItemChecked( nItemId ) )
728 pChild->SetChecked( sal_True );
729 if ( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW )
730 pChild->SetIndeterminate( true );
731 m_aAccessibleChildren.insert( ToolBoxItemsMap::value_type( i, xChild ) );
733 else
735 // found it
736 xChild = aIter->second;
738 return xChild;
741 return NULL;
743 // -----------------------------------------------------------------------------
744 Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point& _rPoint ) throw (RuntimeException)
746 comphelper::OExternalLockGuard aGuard( this );
748 Reference< XAccessible > xAccessible;
749 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
750 if ( pToolBox )
752 sal_uInt16 nItemPos = pToolBox->GetItemPos( VCLPoint( _rPoint ) );
753 if ( nItemPos != TOOLBOX_ITEM_NOTFOUND )
754 xAccessible = getAccessibleChild( nItemPos );
757 return xAccessible;
759 // -----------------------------------------------------------------------------
760 Reference< XAccessible > VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent )
762 Reference< XAccessible > xReturn;
763 Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
764 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
765 if ( pChildWindow && pToolBox )
767 sal_uInt16 nCount = pToolBox->GetItemCount();
768 for (sal_uInt16 i = 0 ; i < nCount && !xReturn.is() ; ++i)
770 sal_uInt16 nItemId = pToolBox->GetItemId( i );
771 Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
772 if ( pItemWindow == pChildWindow )
773 xReturn = getAccessibleChild(i);
776 return xReturn;
778 // -----------------------------------------------------------------------------
779 Reference< XAccessible > VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
781 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
783 if ( !xReturn.is() )
784 xReturn = VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent);
785 return xReturn;
787 // -----------------------------------------------------------------------------
788 // XAccessibleSelection
789 // -----------------------------------------------------------------------------
790 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
792 OExternalLockGuard aGuard( this );
793 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
794 throw IndexOutOfBoundsException();
795 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
796 sal_uInt16 nPos = static_cast < sal_uInt16 > (nChildIndex);
797 pToolBox->ChangeHighlight( nPos );
799 // -----------------------------------------------------------------------------
800 sal_Bool VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
802 OExternalLockGuard aGuard( this );
803 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
804 throw IndexOutOfBoundsException();
805 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
806 sal_uInt16 nPos = static_cast < sal_uInt16 > (nChildIndex);
807 if ( pToolBox != NULL && pToolBox->GetHighlightItemId() == pToolBox->GetItemId( nPos ) )
808 return sal_True;
809 else
810 return sal_False;
812 // -----------------------------------------------------------------------------
813 void VCLXAccessibleToolBox::clearAccessibleSelection( ) throw (RuntimeException)
815 OExternalLockGuard aGuard( this );
816 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
817 pToolBox -> LoseFocus();
819 // -----------------------------------------------------------------------------
820 void VCLXAccessibleToolBox::selectAllAccessibleChildren( ) throw (RuntimeException)
822 OExternalLockGuard aGuard( this );
823 // intentionally empty. makes no sense for a toolbox
825 // -----------------------------------------------------------------------------
826 sal_Int32 VCLXAccessibleToolBox::getSelectedAccessibleChildCount( ) throw (RuntimeException)
828 OExternalLockGuard aGuard( this );
829 sal_Int32 nRet = 0;
830 for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
832 if ( isAccessibleChildSelected( i ) )
834 nRet = 1;
835 break; // a toolbox can only have (n)one selected child
838 return nRet;
840 // -----------------------------------------------------------------------------
841 Reference< XAccessible > VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
843 OExternalLockGuard aGuard( this );
844 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
845 throw IndexOutOfBoundsException();
846 Reference< XAccessible > xChild;
847 for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
849 if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
851 xChild = getAccessibleChild( i );
852 break;
855 return xChild;
857 // -----------------------------------------------------------------------------
858 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
860 OExternalLockGuard aGuard( this );
861 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
862 throw IndexOutOfBoundsException();
863 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
865 // -----------------------------------------------------------------------------
867 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */