merge the formfield patch from ooo-build
[ooovba.git] / accessibility / source / standard / vclxaccessibletoolbox.cxx
blob4795a43a595364f8f14993631df9e7fd3145c92f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vclxaccessibletoolbox.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_accessibility.hxx"
34 // includes --------------------------------------------------------------
35 #include <accessibility/standard/vclxaccessibletoolbox.hxx>
36 #include <accessibility/standard/vclxaccessibletoolboxitem.hxx>
37 #include <toolkit/helper/convert.hxx>
39 #include <unotools/accessiblestatesethelper.hxx>
40 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 #include <com/sun/star/lang/XUnoTunnel.hpp>
43 #include <com/sun/star/lang/XUnoTunnel.hpp>
44 #include <tools/debug.hxx>
45 #include <vcl/toolbox.hxx>
46 #include <comphelper/accessiblewrapper.hxx>
47 #include <comphelper/processfactory.hxx>
49 using namespace ::comphelper;
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::lang;
53 using namespace ::com::sun::star::accessibility;
55 namespace
57 // =========================================================================
58 // = OToolBoxWindowItemContext
59 // =========================================================================
60 /** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window
62 class OToolBoxWindowItemContext : public OAccessibleContextWrapper
64 sal_Int32 m_nIndexInParent;
65 public:
66 OToolBoxWindowItemContext(sal_Int32 _nIndexInParent,
67 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
68 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
69 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible,
70 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
71 ) : OAccessibleContextWrapper(
72 _rxORB,
73 _rxInnerAccessibleContext,
74 _rxOwningAccessible,
75 _rxParentAccessible )
76 ,m_nIndexInParent(_nIndexInParent)
79 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
82 // -------------------------------------------------------------------------
83 sal_Int32 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException)
85 ::osl::MutexGuard aGuard( m_aMutex );
86 return m_nIndexInParent;
89 // =========================================================================
90 // = OToolBoxWindowItem
91 // =========================================================================
92 typedef ::cppu::ImplHelper1 < XUnoTunnel
93 > OToolBoxWindowItem_Base;
95 /** XAccessible implementation for a toolbox item which is represented by a VCL Window
97 class OToolBoxWindowItem
98 :public OAccessibleWrapper
99 ,public OToolBoxWindowItem_Base
101 private:
102 sal_Int32 m_nIndexInParent;
104 public:
105 inline sal_Int32 getIndexInParent() const { return m_nIndexInParent; }
106 inline void setIndexInParent( sal_Int32 _nNewIndex ) { m_nIndexInParent = _nNewIndex; }
108 static sal_Bool isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation = NULL );
110 public:
111 OToolBoxWindowItem(sal_Int32 _nIndexInParent,
112 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
113 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxInnerAccessible,
114 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
115 ) : OAccessibleWrapper(
116 _rxORB,
117 _rxInnerAccessible,
118 _rxParentAccessible)
119 ,m_nIndexInParent(_nIndexInParent)
123 protected:
124 // XInterface
125 DECLARE_XINTERFACE( )
126 DECLARE_XTYPEPROVIDER( )
128 // OAccessibleWrapper
129 virtual OAccessibleContextWrapper* createAccessibleContext(
130 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerContext
133 // XUnoTunnel
134 virtual sal_Int64 SAL_CALL getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw (RuntimeException);
135 static Sequence< sal_Int8 > getUnoTunnelImplementationId();
138 // -------------------------------------------------------------------------
139 IMPLEMENT_FORWARD_XINTERFACE2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
140 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
142 // -------------------------------------------------------------------------
143 OAccessibleContextWrapper* OToolBoxWindowItem::createAccessibleContext(
144 const Reference< XAccessibleContext >& _rxInnerContext )
146 return new OToolBoxWindowItemContext( m_nIndexInParent,getORB(), _rxInnerContext, this, getParent() );
149 //--------------------------------------------------------------------
150 sal_Bool OToolBoxWindowItem::isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation )
152 OToolBoxWindowItem* pImplementation = NULL;
154 Reference< XUnoTunnel > xTunnel( _rxAcc, UNO_QUERY );
155 if ( xTunnel.is() )
156 pImplementation = reinterpret_cast< OToolBoxWindowItem* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
158 if ( _ppImplementation )
159 *_ppImplementation = pImplementation;
161 return NULL != pImplementation;
164 //--------------------------------------------------------------------
165 Sequence< sal_Int8 > OToolBoxWindowItem::getUnoTunnelImplementationId()
167 static ::cppu::OImplementationId * pId = 0;
168 if (! pId)
170 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
171 if (! pId)
173 static ::cppu::OImplementationId aId;
174 pId = &aId;
177 return pId->getImplementationId();
180 //--------------------------------------------------------------------
181 sal_Int64 SAL_CALL OToolBoxWindowItem::getSomething( const Sequence< sal_Int8 >& _rId ) throw (RuntimeException)
183 if ( ( 16 == _rId.getLength() )
184 && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rId.getConstArray(), 16 ) )
186 return reinterpret_cast< sal_Int64>( this );
188 return 0;
192 DBG_NAME(VCLXAccessibleToolBox)
194 // -----------------------------------------------------------------------------
195 // VCLXAccessibleToolBox
196 // -----------------------------------------------------------------------------
197 VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ) :
199 VCLXAccessibleComponent( pVCLXWindow )
202 DBG_CTOR(VCLXAccessibleToolBox,NULL);
204 // -----------------------------------------------------------------------------
205 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
207 DBG_DTOR(VCLXAccessibleToolBox,NULL);
209 // -----------------------------------------------------------------------------
210 VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( sal_Int32 _nPos, bool _bMustHaveFocus )
212 VCLXAccessibleToolBoxItem* pItem = NULL;
213 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
214 if ( pToolBox && ( !_bMustHaveFocus || pToolBox->HasFocus() ) )
216 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
217 // returns only toolbox buttons, not windows
218 if ( aIter != m_aAccessibleChildren.end() && !aIter->second.is())
219 pItem = static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
222 return pItem;
224 // -----------------------------------------------------------------------------
226 void VCLXAccessibleToolBox::UpdateFocus_Impl()
228 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
229 if( !pToolBox )
230 return;
232 // submit events only if toolbox has the focus to avoid sending events due to mouse move
233 BOOL bHasFocus = FALSE;
234 if ( pToolBox->HasFocus() )
235 bHasFocus = TRUE;
236 else
238 // check for subtoolbar, i.e. check if our parent is a toolbar
239 ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
240 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
241 if ( pToolBoxParent && pToolBoxParent->HasFocus() )
242 bHasFocus = TRUE;
245 if ( bHasFocus )
247 USHORT nHighlightItemId = pToolBox->GetHighlightItemId();
248 USHORT nFocusCount = 0;
249 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
250 aIter != m_aAccessibleChildren.end(); ++aIter )
252 USHORT nItemId = pToolBox->GetItemId( (USHORT)aIter->first );
254 if ( aIter->second.is() )
256 VCLXAccessibleToolBoxItem* pItem =
257 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
258 if ( pItem->HasFocus() && nItemId != nHighlightItemId )
260 // reset the old focused item
261 pItem->SetFocus( sal_False );
262 nFocusCount++;
264 if ( nItemId == nHighlightItemId )
266 // set the new focused item
267 pItem->SetFocus( sal_True );
268 nFocusCount++;
271 // both items changed?
272 if ( nFocusCount > 1 )
273 break;
277 // -----------------------------------------------------------------------------
278 void VCLXAccessibleToolBox::ReleaseFocus_Impl( sal_Int32 _nPos )
280 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
281 if ( pToolBox ) // #107124#, do not check for focus because this message is also handled in losefocus
283 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
284 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
286 VCLXAccessibleToolBoxItem* pItem =
287 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
288 if ( pItem->HasFocus() )
289 pItem->SetFocus( sal_False );
293 // -----------------------------------------------------------------------------
294 void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 )
296 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
297 if ( pToolBox )
299 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
300 aIter != m_aAccessibleChildren.end(); ++aIter )
302 USHORT nItemId = pToolBox->GetItemId( (USHORT)aIter->first );
304 VCLXAccessibleToolBoxItem* pItem =
305 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
306 pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) );
310 // -----------------------------------------------------------------------------
311 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( sal_Int32 _nPos )
313 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
314 if ( pToolBox )
316 USHORT nItemId = pToolBox->GetItemId( (USHORT)_nPos );
318 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
319 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
321 VCLXAccessibleToolBoxItem* pItem =
322 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
323 if ( pItem )
324 pItem->SetIndeterminate( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW );
328 // -----------------------------------------------------------------------------
329 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator& _rMapPos,
330 bool _bNotifyRemoval, bool _bDispose )
332 Reference< XAccessible > xItemAcc( _rMapPos->second );
333 if ( !xItemAcc.is() )
334 return;
336 if ( _bNotifyRemoval )
338 NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( xItemAcc ), Any() );
341 OToolBoxWindowItem* pWindowItem = NULL;
342 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
344 static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() )->ReleaseToolBox();
345 if ( _bDispose )
346 ::comphelper::disposeComponent( xItemAcc );
348 else
350 if ( _bDispose )
352 if ( pWindowItem )
354 Reference< XAccessibleContext > xContext( pWindowItem->getContextNoCreate() );
355 ::comphelper::disposeComponent( xContext );
361 // -----------------------------------------------------------------------------
362 void VCLXAccessibleToolBox::UpdateItem_Impl( sal_Int32 _nPos, sal_Bool _bItemAdded )
364 if ( _nPos < sal_Int32( m_aAccessibleChildren.size() ) )
366 UpdateAllItems_Impl();
367 return;
370 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
371 if ( pToolBox )
373 if ( !_bItemAdded )
374 { // the item was removed
375 // -> destroy the old item
376 ToolBoxItemsMap::iterator aItemPos = m_aAccessibleChildren.find( _nPos );
377 if ( m_aAccessibleChildren.end() != aItemPos )
379 implReleaseToolboxItem( aItemPos, true, true );
380 m_aAccessibleChildren.erase( aItemPos );
384 // adjust the "index-in-parent"s
385 ToolBoxItemsMap::iterator aIndexAdjust = m_aAccessibleChildren.upper_bound( _nPos );
386 while ( m_aAccessibleChildren.end() != aIndexAdjust )
388 Reference< XAccessible > xItemAcc( aIndexAdjust->second );
390 OToolBoxWindowItem* pWindowItem = NULL;
391 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
393 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() );
394 if ( pItem )
396 sal_Int32 nIndex = pItem->getIndexInParent( );
397 nIndex += _bItemAdded ? +1 : -1;
398 pItem->setIndexInParent( nIndex );
401 else
403 if ( pWindowItem )
405 sal_Int32 nIndex = pWindowItem->getIndexInParent( );
406 nIndex += _bItemAdded ? +1 : -1;
407 pWindowItem->setIndexInParent( nIndex );
411 ++aIndexAdjust;
414 if ( _bItemAdded )
416 // TODO: we should make this dependent on the existence of event listeners
417 // with the current implementation, we always create accessible object
418 Any aNewChild = makeAny( getAccessibleChild( (sal_Int32)_nPos ) );
419 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewChild );
423 // -----------------------------------------------------------------------------
424 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
426 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
427 if ( pToolBox )
429 // deregister the old items
430 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
431 aIter != m_aAccessibleChildren.end(); ++aIter )
433 implReleaseToolboxItem( aIter, true, true );
435 m_aAccessibleChildren.clear();
437 // register the new items
438 USHORT i, nCount = pToolBox->GetItemCount();
439 for ( i = 0; i < nCount; ++i )
441 Any aNewValue;
442 aNewValue <<= getAccessibleChild( (sal_Int32)i );;
443 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
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_OBJECT_DYING :
590 // if this toolbox is a subtoolbox, we have to relese it from its parent
591 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
592 if ( pToolBox && pToolBox->GetParent() &&
593 pToolBox->GetParent()->GetType() == WINDOW_TOOLBOX )
595 VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >(
596 pToolBox->GetParent()->GetAccessible()->getAccessibleContext().get() );
597 if ( pParent )
598 pParent->ReleaseSubToolBox( pToolBox );
601 // dispose all items
602 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
603 aIter != m_aAccessibleChildren.end(); ++aIter )
605 implReleaseToolboxItem( aIter, false, true );
607 m_aAccessibleChildren.clear();
609 //!!! no break to call base class
612 default:
613 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
616 // -----------------------------------------------------------------------------
617 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
619 switch ( rVclWindowEvent.GetId() )
621 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
623 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
624 if ( xReturn.is() )
625 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny(xReturn) );
626 else
627 HandleSubToolBarEvent( rVclWindowEvent, true );
629 break;
631 default:
632 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
636 // -----------------------------------------------------------------------------
637 // XInterface
638 // -----------------------------------------------------------------------------
639 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
640 // -----------------------------------------------------------------------------
641 // XTypeProvider
642 // -----------------------------------------------------------------------------
643 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
644 // -----------------------------------------------------------------------------
645 // XComponent
646 // -----------------------------------------------------------------------------
647 void SAL_CALL VCLXAccessibleToolBox::disposing()
649 VCLXAccessibleComponent::disposing();
651 // release the items
652 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
653 aIter != m_aAccessibleChildren.end(); ++aIter )
655 implReleaseToolboxItem( aIter, false, true );
657 m_aAccessibleChildren.clear();
659 // -----------------------------------------------------------------------------
660 // XServiceInfo
661 // -----------------------------------------------------------------------------
662 ::rtl::OUString VCLXAccessibleToolBox::getImplementationName() throw (RuntimeException)
664 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleToolBox" );
666 // -----------------------------------------------------------------------------
667 Sequence< ::rtl::OUString > VCLXAccessibleToolBox::getSupportedServiceNames() throw (RuntimeException)
669 Sequence< ::rtl::OUString > aNames = VCLXAccessibleComponent::getSupportedServiceNames();
670 sal_Int32 nLength = aNames.getLength();
671 aNames.realloc( nLength + 1 );
672 aNames[nLength] = ::rtl::OUString::createFromAscii( "com.sun.star.accessibility.AccessibleToolBox" );
673 return aNames;
675 // -----------------------------------------------------------------------------
676 // XAccessibleContext
677 // -----------------------------------------------------------------------------
678 sal_Int32 SAL_CALL VCLXAccessibleToolBox::getAccessibleChildCount( ) throw (RuntimeException)
680 comphelper::OExternalLockGuard aGuard( this );
682 sal_Int32 nCount = 0;
683 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
684 if ( pToolBox )
685 nCount = pToolBox->GetItemCount();
687 return nCount;
689 // -----------------------------------------------------------------------------
690 Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
692 if ( i < 0 || i >= getAccessibleChildCount() )
693 throw IndexOutOfBoundsException();
695 comphelper::OExternalLockGuard aGuard( this );
697 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
698 if ( pToolBox )
700 Reference< XAccessible > xChild;
701 // search for the child
702 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find(i);
703 if ( m_aAccessibleChildren.end() == aIter )
705 USHORT nItemId = pToolBox->GetItemId( (USHORT)i );
706 USHORT nHighlightItemId = pToolBox->GetHighlightItemId();
707 Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
708 // not found -> create a new child
709 VCLXAccessibleToolBoxItem* pChild = new VCLXAccessibleToolBoxItem( pToolBox, i );
710 Reference< XAccessible> xParent = pChild;
711 if ( pItemWindow )
713 xChild = new OToolBoxWindowItem(0,::comphelper::getProcessServiceFactory(),pItemWindow->GetAccessible(),xParent);
714 pItemWindow->SetAccessible(xChild);
715 pChild->SetChild( xChild );
717 xChild = pChild;
718 if ( nHighlightItemId > 0 && nItemId == nHighlightItemId )
719 pChild->SetFocus( sal_True );
720 if ( pToolBox->IsItemChecked( nItemId ) )
721 pChild->SetChecked( sal_True );
722 if ( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW )
723 pChild->SetIndeterminate( true );
724 m_aAccessibleChildren.insert( ToolBoxItemsMap::value_type( i, xChild ) );
726 else
728 // found it
729 xChild = aIter->second;
731 return xChild;
734 return NULL;
736 // -----------------------------------------------------------------------------
737 Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point& _rPoint ) throw (RuntimeException)
739 comphelper::OExternalLockGuard aGuard( this );
741 Reference< XAccessible > xAccessible;
742 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
743 if ( pToolBox )
745 USHORT nItemPos = pToolBox->GetItemPos( VCLPoint( _rPoint ) );
746 if ( nItemPos != TOOLBOX_ITEM_NOTFOUND )
747 xAccessible = getAccessibleChild( nItemPos );
750 return xAccessible;
752 // -----------------------------------------------------------------------------
753 Reference< XAccessible > VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent )
755 Reference< XAccessible > xReturn;
756 Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
757 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
758 if ( pChildWindow && pToolBox )
760 USHORT nCount = pToolBox->GetItemCount();
761 for (USHORT i = 0 ; i < nCount && !xReturn.is() ; ++i)
763 USHORT nItemId = pToolBox->GetItemId( i );
764 Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
765 if ( pItemWindow == pChildWindow )
766 xReturn = getAccessibleChild(i);
769 return xReturn;
771 // -----------------------------------------------------------------------------
772 Reference< XAccessible > VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
774 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
776 if ( !xReturn.is() )
777 xReturn = VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent);
778 return xReturn;
780 // -----------------------------------------------------------------------------
781 // XAccessibleSelection
782 // -----------------------------------------------------------------------------
783 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
785 OExternalLockGuard aGuard( this );
786 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
787 throw IndexOutOfBoundsException();
788 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
789 USHORT nPos = static_cast < USHORT > (nChildIndex);
790 pToolBox->ChangeHighlight( nPos );
792 // -----------------------------------------------------------------------------
793 sal_Bool VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
795 OExternalLockGuard aGuard( this );
796 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
797 throw IndexOutOfBoundsException();
798 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
799 USHORT nPos = static_cast < USHORT > (nChildIndex);
800 if ( pToolBox != NULL && pToolBox->GetHighlightItemId() == pToolBox->GetItemId( nPos ) )
801 return sal_True;
802 else
803 return sal_False;
805 // -----------------------------------------------------------------------------
806 void VCLXAccessibleToolBox::clearAccessibleSelection( ) throw (RuntimeException)
808 OExternalLockGuard aGuard( this );
809 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
810 pToolBox -> LoseFocus();
812 // -----------------------------------------------------------------------------
813 void VCLXAccessibleToolBox::selectAllAccessibleChildren( ) throw (RuntimeException)
815 OExternalLockGuard aGuard( this );
816 // intentionally empty. makes no sense for a toolbox
818 // -----------------------------------------------------------------------------
819 sal_Int32 VCLXAccessibleToolBox::getSelectedAccessibleChildCount( ) throw (RuntimeException)
821 OExternalLockGuard aGuard( this );
822 sal_Int32 nRet = 0;
823 for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
825 if ( isAccessibleChildSelected( i ) )
827 nRet = 1;
828 break; // a toolbox can only have (n)one selected child
831 return nRet;
833 // -----------------------------------------------------------------------------
834 Reference< XAccessible > VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
836 OExternalLockGuard aGuard( this );
837 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
838 throw IndexOutOfBoundsException();
839 Reference< XAccessible > xChild;
840 for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
842 if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
844 xChild = getAccessibleChild( i );
845 break;
848 return xChild;
850 // -----------------------------------------------------------------------------
851 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
853 OExternalLockGuard aGuard( this );
854 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
855 throw IndexOutOfBoundsException();
856 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
858 // -----------------------------------------------------------------------------