merged tag ooo/DEV300_m102
[LibreOffice.git] / accessibility / source / standard / vclxaccessibletoolbox.cxx
bloba11e1d52c7e3fc2b3bd77f041fd138ae462a468d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_accessibility.hxx"
31 // includes --------------------------------------------------------------
32 #include <accessibility/standard/vclxaccessibletoolbox.hxx>
33 #include <accessibility/standard/vclxaccessibletoolboxitem.hxx>
34 #include <toolkit/helper/convert.hxx>
36 #include <unotools/accessiblestatesethelper.hxx>
37 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 #include <com/sun/star/lang/XUnoTunnel.hpp>
40 #include <com/sun/star/lang/XUnoTunnel.hpp>
41 #include <tools/debug.hxx>
42 #include <vcl/toolbox.hxx>
43 #include <comphelper/accessiblewrapper.hxx>
44 #include <comphelper/processfactory.hxx>
46 using namespace ::comphelper;
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::accessibility;
52 namespace
54 // =========================================================================
55 // = OToolBoxWindowItemContext
56 // =========================================================================
57 /** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window
59 class OToolBoxWindowItemContext : public OAccessibleContextWrapper
61 sal_Int32 m_nIndexInParent;
62 public:
63 OToolBoxWindowItemContext(sal_Int32 _nIndexInParent,
64 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
65 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
66 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible,
67 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
68 ) : OAccessibleContextWrapper(
69 _rxORB,
70 _rxInnerAccessibleContext,
71 _rxOwningAccessible,
72 _rxParentAccessible )
73 ,m_nIndexInParent(_nIndexInParent)
76 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
79 // -------------------------------------------------------------------------
80 sal_Int32 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException)
82 ::osl::MutexGuard aGuard( m_aMutex );
83 return m_nIndexInParent;
86 // =========================================================================
87 // = OToolBoxWindowItem
88 // =========================================================================
89 typedef ::cppu::ImplHelper1 < XUnoTunnel
90 > OToolBoxWindowItem_Base;
92 /** XAccessible implementation for a toolbox item which is represented by a VCL Window
94 class OToolBoxWindowItem
95 :public OAccessibleWrapper
96 ,public OToolBoxWindowItem_Base
98 private:
99 sal_Int32 m_nIndexInParent;
101 public:
102 inline sal_Int32 getIndexInParent() const { return m_nIndexInParent; }
103 inline void setIndexInParent( sal_Int32 _nNewIndex ) { m_nIndexInParent = _nNewIndex; }
105 static sal_Bool isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation = NULL );
107 public:
108 OToolBoxWindowItem(sal_Int32 _nIndexInParent,
109 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
110 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxInnerAccessible,
111 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
112 ) : OAccessibleWrapper(
113 _rxORB,
114 _rxInnerAccessible,
115 _rxParentAccessible)
116 ,m_nIndexInParent(_nIndexInParent)
120 protected:
121 // XInterface
122 DECLARE_XINTERFACE( )
123 DECLARE_XTYPEPROVIDER( )
125 // OAccessibleWrapper
126 virtual OAccessibleContextWrapper* createAccessibleContext(
127 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerContext
130 // XUnoTunnel
131 virtual sal_Int64 SAL_CALL getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw (RuntimeException);
132 static Sequence< sal_Int8 > getUnoTunnelImplementationId();
135 // -------------------------------------------------------------------------
136 IMPLEMENT_FORWARD_XINTERFACE2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
137 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
139 // -------------------------------------------------------------------------
140 OAccessibleContextWrapper* OToolBoxWindowItem::createAccessibleContext(
141 const Reference< XAccessibleContext >& _rxInnerContext )
143 return new OToolBoxWindowItemContext( m_nIndexInParent,getORB(), _rxInnerContext, this, getParent() );
146 //--------------------------------------------------------------------
147 sal_Bool OToolBoxWindowItem::isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation )
149 OToolBoxWindowItem* pImplementation = NULL;
151 Reference< XUnoTunnel > xTunnel( _rxAcc, UNO_QUERY );
152 if ( xTunnel.is() )
153 pImplementation = reinterpret_cast< OToolBoxWindowItem* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
155 if ( _ppImplementation )
156 *_ppImplementation = pImplementation;
158 return NULL != pImplementation;
161 //--------------------------------------------------------------------
162 Sequence< sal_Int8 > OToolBoxWindowItem::getUnoTunnelImplementationId()
164 static ::cppu::OImplementationId * pId = 0;
165 if (! pId)
167 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
168 if (! pId)
170 static ::cppu::OImplementationId aId;
171 pId = &aId;
174 return pId->getImplementationId();
177 //--------------------------------------------------------------------
178 sal_Int64 SAL_CALL OToolBoxWindowItem::getSomething( const Sequence< sal_Int8 >& _rId ) throw (RuntimeException)
180 if ( ( 16 == _rId.getLength() )
181 && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rId.getConstArray(), 16 ) )
183 return reinterpret_cast< sal_Int64>( this );
185 return 0;
189 DBG_NAME(VCLXAccessibleToolBox)
191 // -----------------------------------------------------------------------------
192 // VCLXAccessibleToolBox
193 // -----------------------------------------------------------------------------
194 VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ) :
196 VCLXAccessibleComponent( pVCLXWindow )
199 DBG_CTOR(VCLXAccessibleToolBox,NULL);
201 // -----------------------------------------------------------------------------
202 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
204 DBG_DTOR(VCLXAccessibleToolBox,NULL);
206 // -----------------------------------------------------------------------------
207 VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( sal_Int32 _nPos, bool _bMustHaveFocus )
209 VCLXAccessibleToolBoxItem* pItem = NULL;
210 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
211 if ( pToolBox && ( !_bMustHaveFocus || pToolBox->HasFocus() ) )
213 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
214 // returns only toolbox buttons, not windows
215 if ( aIter != m_aAccessibleChildren.end() && !aIter->second.is())
216 pItem = static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
219 return pItem;
221 // -----------------------------------------------------------------------------
223 void VCLXAccessibleToolBox::UpdateFocus_Impl()
225 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
226 if( !pToolBox )
227 return;
229 // submit events only if toolbox has the focus to avoid sending events due to mouse move
230 sal_Bool bHasFocus = sal_False;
231 if ( pToolBox->HasFocus() )
232 bHasFocus = sal_True;
233 else
235 // check for subtoolbar, i.e. check if our parent is a toolbar
236 ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
237 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
238 if ( pToolBoxParent && pToolBoxParent->HasFocus() )
239 bHasFocus = sal_True;
242 if ( bHasFocus )
244 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
245 sal_uInt16 nFocusCount = 0;
246 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
247 aIter != m_aAccessibleChildren.end(); ++aIter )
249 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)aIter->first );
251 if ( aIter->second.is() )
253 VCLXAccessibleToolBoxItem* pItem =
254 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
255 if ( pItem->HasFocus() && nItemId != nHighlightItemId )
257 // reset the old focused item
258 pItem->SetFocus( sal_False );
259 nFocusCount++;
261 if ( nItemId == nHighlightItemId )
263 // set the new focused item
264 pItem->SetFocus( sal_True );
265 nFocusCount++;
268 // both items changed?
269 if ( nFocusCount > 1 )
270 break;
274 // -----------------------------------------------------------------------------
275 void VCLXAccessibleToolBox::ReleaseFocus_Impl( sal_Int32 _nPos )
277 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
278 if ( pToolBox ) // #107124#, do not check for focus because this message is also handled in losefocus
280 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
281 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
283 VCLXAccessibleToolBoxItem* pItem =
284 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
285 if ( pItem->HasFocus() )
286 pItem->SetFocus( sal_False );
290 // -----------------------------------------------------------------------------
291 void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 )
293 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
294 if ( pToolBox )
296 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
297 aIter != m_aAccessibleChildren.end(); ++aIter )
299 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)aIter->first );
301 VCLXAccessibleToolBoxItem* pItem =
302 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
303 pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) );
307 // -----------------------------------------------------------------------------
308 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( sal_Int32 _nPos )
310 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
311 if ( pToolBox )
313 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)_nPos );
315 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
316 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
318 VCLXAccessibleToolBoxItem* pItem =
319 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
320 if ( pItem )
321 pItem->SetIndeterminate( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW );
325 // -----------------------------------------------------------------------------
326 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator& _rMapPos,
327 bool _bNotifyRemoval, bool _bDispose )
329 Reference< XAccessible > xItemAcc( _rMapPos->second );
330 if ( !xItemAcc.is() )
331 return;
333 if ( _bNotifyRemoval )
335 NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( xItemAcc ), Any() );
338 OToolBoxWindowItem* pWindowItem = NULL;
339 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
341 static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() )->ReleaseToolBox();
342 if ( _bDispose )
343 ::comphelper::disposeComponent( xItemAcc );
345 else
347 if ( _bDispose )
349 if ( pWindowItem )
351 Reference< XAccessibleContext > xContext( pWindowItem->getContextNoCreate() );
352 ::comphelper::disposeComponent( xContext );
358 // -----------------------------------------------------------------------------
359 void VCLXAccessibleToolBox::UpdateItem_Impl( sal_Int32 _nPos, sal_Bool _bItemAdded )
361 if ( _nPos < sal_Int32( m_aAccessibleChildren.size() ) )
363 UpdateAllItems_Impl();
364 return;
367 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
368 if ( pToolBox )
370 if ( !_bItemAdded )
371 { // the item was removed
372 // -> destroy the old item
373 ToolBoxItemsMap::iterator aItemPos = m_aAccessibleChildren.find( _nPos );
374 if ( m_aAccessibleChildren.end() != aItemPos )
376 implReleaseToolboxItem( aItemPos, true, true );
377 m_aAccessibleChildren.erase( aItemPos );
381 // adjust the "index-in-parent"s
382 ToolBoxItemsMap::iterator aIndexAdjust = m_aAccessibleChildren.upper_bound( _nPos );
383 while ( m_aAccessibleChildren.end() != aIndexAdjust )
385 Reference< XAccessible > xItemAcc( aIndexAdjust->second );
387 OToolBoxWindowItem* pWindowItem = NULL;
388 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
390 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() );
391 if ( pItem )
393 sal_Int32 nIndex = pItem->getIndexInParent( );
394 nIndex += _bItemAdded ? +1 : -1;
395 pItem->setIndexInParent( nIndex );
398 else
400 if ( pWindowItem )
402 sal_Int32 nIndex = pWindowItem->getIndexInParent( );
403 nIndex += _bItemAdded ? +1 : -1;
404 pWindowItem->setIndexInParent( nIndex );
408 ++aIndexAdjust;
411 if ( _bItemAdded )
413 // TODO: we should make this dependent on the existence of event listeners
414 // with the current implementation, we always create accessible object
415 Any aNewChild = makeAny( getAccessibleChild( (sal_Int32)_nPos ) );
416 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewChild );
420 // -----------------------------------------------------------------------------
421 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
423 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
424 if ( pToolBox )
426 // deregister the old items
427 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
428 aIter != m_aAccessibleChildren.end(); ++aIter )
430 implReleaseToolboxItem( aIter, true, true );
432 m_aAccessibleChildren.clear();
434 // register the new items
435 sal_uInt16 i, nCount = pToolBox->GetItemCount();
436 for ( i = 0; i < nCount; ++i )
438 Any aNewValue;
439 aNewValue <<= getAccessibleChild( (sal_Int32)i );;
440 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
445 // -----------------------------------------------------------------------------
447 void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( Window* pWindow, bool bOpen )
449 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
450 if( pWindow && pToolBox )
452 Reference< XAccessible > xChild( pWindow->GetAccessible() );
453 if( xChild.is() )
455 Reference< XAccessible > xChildItem( getAccessibleChild( static_cast< sal_Int32 >( pToolBox->GetItemPos( pToolBox->GetDownItemId() ) ) ) );
456 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xChildItem.get() );
458 pItem->SetChild( xChild );
459 pItem->NotifyChildEvent( xChild, bOpen );
464 // -----------------------------------------------------------------------------
465 void VCLXAccessibleToolBox::UpdateItemName_Impl( sal_Int32 _nPos )
467 VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos, false );
468 if ( pItem )
469 pItem->NameChanged();
471 // -----------------------------------------------------------------------------
472 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( sal_Int32 _nPos )
474 VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos, false );
475 if ( pItem )
476 pItem->ToggleEnableState();
478 // -----------------------------------------------------------------------------
479 void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent& rVclWindowEvent, bool _bShow )
481 Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
482 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
483 if ( pChildWindow
484 && pToolBox
485 && pToolBox == pChildWindow->GetParent()
486 && pChildWindow->GetType() == WINDOW_TOOLBOX )
488 sal_Int32 nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
489 Reference< XAccessible > xItem = getAccessibleChild( nIndex );
490 if ( xItem.is() )
492 Reference< XAccessible > xChild = pChildWindow->GetAccessible();
493 VCLXAccessibleToolBoxItem* pItem =
494 static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
495 pItem->SetChild( xChild );
496 pItem->NotifyChildEvent( xChild, _bShow );
500 // -----------------------------------------------------------------------------
501 void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox* _pSubToolBox )
503 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
504 if ( pToolBox )
506 sal_Int32 nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
507 Reference< XAccessible > xItem = getAccessibleChild( nIndex );
508 if ( xItem.is() )
510 Reference< XAccessible > xChild = _pSubToolBox->GetAccessible();
511 VCLXAccessibleToolBoxItem* pItem =
512 static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
513 if ( pItem->GetChild() == xChild )
515 pItem->SetChild( Reference< XAccessible >() );
516 pItem->NotifyChildEvent( xChild, false );
521 // -----------------------------------------------------------------------------
522 void VCLXAccessibleToolBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
524 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
526 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
527 if ( pToolBox )
529 rStateSet.AddState( AccessibleStateType::FOCUSABLE );
530 if ( pToolBox->IsHorizontal() )
531 rStateSet.AddState( AccessibleStateType::HORIZONTAL );
532 else
533 rStateSet.AddState( AccessibleStateType::VERTICAL );
536 // -----------------------------------------------------------------------------
537 void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
539 // to prevent an early release of the toolbox (VCLEVENT_OBJECT_DYING)
540 Reference< XAccessibleContext > xTemp = this;
542 switch ( rVclWindowEvent.GetId() )
544 case VCLEVENT_TOOLBOX_CLICK:
546 if ( rVclWindowEvent.GetData() )
548 UpdateChecked_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
549 UpdateIndeterminate_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
551 break;
553 case VCLEVENT_TOOLBOX_DOUBLECLICK:
554 case VCLEVENT_TOOLBOX_ACTIVATE:
555 case VCLEVENT_TOOLBOX_DEACTIVATE:
556 case VCLEVENT_TOOLBOX_SELECT:
557 break;
559 case VCLEVENT_TOOLBOX_HIGHLIGHT:
560 UpdateFocus_Impl();
561 break;
563 case VCLEVENT_TOOLBOX_HIGHLIGHTOFF:
564 ReleaseFocus_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
565 break;
567 case VCLEVENT_TOOLBOX_ITEMADDED :
568 // UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), VCLEVENT_TOOLBOX_ITEMADDED == rVclWindowEvent.GetId() );
569 UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), sal_True );
570 break;
572 case VCLEVENT_TOOLBOX_ITEMREMOVED :
573 case VCLEVENT_TOOLBOX_ALLITEMSCHANGED :
575 UpdateAllItems_Impl();
576 break;
579 case VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED:
581 sal_Int32 nPos = (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData();
582 ToolBoxItemsMap::iterator aAccessiblePos( m_aAccessibleChildren.find( nPos ) );
583 if ( m_aAccessibleChildren.end() != aAccessiblePos )
585 implReleaseToolboxItem( aAccessiblePos, false, true );
586 m_aAccessibleChildren.erase (aAccessiblePos);
589 Any aNewValue;
590 aNewValue <<= getAccessibleChild(nPos);
591 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
592 break;
594 case VCLEVENT_TOOLBOX_ITEMTEXTCHANGED :
595 UpdateItemName_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
596 break;
598 case VCLEVENT_TOOLBOX_ITEMENABLED :
599 case VCLEVENT_TOOLBOX_ITEMDISABLED :
601 UpdateItemEnabled_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
602 break;
605 case VCLEVENT_DROPDOWN_OPEN:
606 case VCLEVENT_DROPDOWN_CLOSE:
608 UpdateCustomPopupItemp_Impl( static_cast< Window* >( rVclWindowEvent.GetData() ), rVclWindowEvent.GetId() == VCLEVENT_DROPDOWN_OPEN );
609 break;
612 case VCLEVENT_OBJECT_DYING :
614 // if this toolbox is a subtoolbox, we have to relese it from its parent
615 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
616 if ( pToolBox && pToolBox->GetParent() &&
617 pToolBox->GetParent()->GetType() == WINDOW_TOOLBOX )
619 VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >(
620 pToolBox->GetParent()->GetAccessible()->getAccessibleContext().get() );
621 if ( pParent )
622 pParent->ReleaseSubToolBox( pToolBox );
625 // dispose all items
626 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
627 aIter != m_aAccessibleChildren.end(); ++aIter )
629 implReleaseToolboxItem( aIter, false, true );
631 m_aAccessibleChildren.clear();
633 //!!! no break to call base class
636 default:
637 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
640 // -----------------------------------------------------------------------------
641 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
643 switch ( rVclWindowEvent.GetId() )
645 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
647 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
648 if ( xReturn.is() )
649 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny(xReturn) );
650 else
651 HandleSubToolBarEvent( rVclWindowEvent, true );
653 break;
655 default:
656 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
660 // -----------------------------------------------------------------------------
661 // XInterface
662 // -----------------------------------------------------------------------------
663 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
664 // -----------------------------------------------------------------------------
665 // XTypeProvider
666 // -----------------------------------------------------------------------------
667 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
668 // -----------------------------------------------------------------------------
669 // XComponent
670 // -----------------------------------------------------------------------------
671 void SAL_CALL VCLXAccessibleToolBox::disposing()
673 VCLXAccessibleComponent::disposing();
675 // release the items
676 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
677 aIter != m_aAccessibleChildren.end(); ++aIter )
679 implReleaseToolboxItem( aIter, false, true );
681 m_aAccessibleChildren.clear();
683 // -----------------------------------------------------------------------------
684 // XServiceInfo
685 // -----------------------------------------------------------------------------
686 ::rtl::OUString VCLXAccessibleToolBox::getImplementationName() throw (RuntimeException)
688 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleToolBox" );
690 // -----------------------------------------------------------------------------
691 Sequence< ::rtl::OUString > VCLXAccessibleToolBox::getSupportedServiceNames() throw (RuntimeException)
693 Sequence< ::rtl::OUString > aNames = VCLXAccessibleComponent::getSupportedServiceNames();
694 sal_Int32 nLength = aNames.getLength();
695 aNames.realloc( nLength + 1 );
696 aNames[nLength] = ::rtl::OUString::createFromAscii( "com.sun.star.accessibility.AccessibleToolBox" );
697 return aNames;
699 // -----------------------------------------------------------------------------
700 // XAccessibleContext
701 // -----------------------------------------------------------------------------
702 sal_Int32 SAL_CALL VCLXAccessibleToolBox::getAccessibleChildCount( ) throw (RuntimeException)
704 comphelper::OExternalLockGuard aGuard( this );
706 sal_Int32 nCount = 0;
707 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
708 if ( pToolBox )
709 nCount = pToolBox->GetItemCount();
711 return nCount;
713 // -----------------------------------------------------------------------------
714 Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
716 if ( i < 0 || i >= getAccessibleChildCount() )
717 throw IndexOutOfBoundsException();
719 comphelper::OExternalLockGuard aGuard( this );
721 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
722 if ( pToolBox )
724 Reference< XAccessible > xChild;
725 // search for the child
726 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find(i);
727 if ( m_aAccessibleChildren.end() == aIter )
729 sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)i );
730 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
731 Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
732 // not found -> create a new child
733 VCLXAccessibleToolBoxItem* pChild = new VCLXAccessibleToolBoxItem( pToolBox, i );
734 Reference< XAccessible> xParent = pChild;
735 if ( pItemWindow )
737 xChild = new OToolBoxWindowItem(0,::comphelper::getProcessServiceFactory(),pItemWindow->GetAccessible(),xParent);
738 pItemWindow->SetAccessible(xChild);
739 pChild->SetChild( xChild );
741 xChild = pChild;
742 if ( nHighlightItemId > 0 && nItemId == nHighlightItemId )
743 pChild->SetFocus( sal_True );
744 if ( pToolBox->IsItemChecked( nItemId ) )
745 pChild->SetChecked( sal_True );
746 if ( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW )
747 pChild->SetIndeterminate( true );
748 m_aAccessibleChildren.insert( ToolBoxItemsMap::value_type( i, xChild ) );
750 else
752 // found it
753 xChild = aIter->second;
755 return xChild;
758 return NULL;
760 // -----------------------------------------------------------------------------
761 Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point& _rPoint ) throw (RuntimeException)
763 comphelper::OExternalLockGuard aGuard( this );
765 Reference< XAccessible > xAccessible;
766 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
767 if ( pToolBox )
769 sal_uInt16 nItemPos = pToolBox->GetItemPos( VCLPoint( _rPoint ) );
770 if ( nItemPos != TOOLBOX_ITEM_NOTFOUND )
771 xAccessible = getAccessibleChild( nItemPos );
774 return xAccessible;
776 // -----------------------------------------------------------------------------
777 Reference< XAccessible > VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent )
779 Reference< XAccessible > xReturn;
780 Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
781 ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
782 if ( pChildWindow && pToolBox )
784 sal_uInt16 nCount = pToolBox->GetItemCount();
785 for (sal_uInt16 i = 0 ; i < nCount && !xReturn.is() ; ++i)
787 sal_uInt16 nItemId = pToolBox->GetItemId( i );
788 Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
789 if ( pItemWindow == pChildWindow )
790 xReturn = getAccessibleChild(i);
793 return xReturn;
795 // -----------------------------------------------------------------------------
796 Reference< XAccessible > VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
798 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
800 if ( !xReturn.is() )
801 xReturn = VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent);
802 return xReturn;
804 // -----------------------------------------------------------------------------
805 // XAccessibleSelection
806 // -----------------------------------------------------------------------------
807 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
809 OExternalLockGuard aGuard( this );
810 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
811 throw IndexOutOfBoundsException();
812 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
813 sal_uInt16 nPos = static_cast < sal_uInt16 > (nChildIndex);
814 pToolBox->ChangeHighlight( nPos );
816 // -----------------------------------------------------------------------------
817 sal_Bool VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
819 OExternalLockGuard aGuard( this );
820 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
821 throw IndexOutOfBoundsException();
822 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
823 sal_uInt16 nPos = static_cast < sal_uInt16 > (nChildIndex);
824 if ( pToolBox != NULL && pToolBox->GetHighlightItemId() == pToolBox->GetItemId( nPos ) )
825 return sal_True;
826 else
827 return sal_False;
829 // -----------------------------------------------------------------------------
830 void VCLXAccessibleToolBox::clearAccessibleSelection( ) throw (RuntimeException)
832 OExternalLockGuard aGuard( this );
833 ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
834 pToolBox -> LoseFocus();
836 // -----------------------------------------------------------------------------
837 void VCLXAccessibleToolBox::selectAllAccessibleChildren( ) throw (RuntimeException)
839 OExternalLockGuard aGuard( this );
840 // intentionally empty. makes no sense for a toolbox
842 // -----------------------------------------------------------------------------
843 sal_Int32 VCLXAccessibleToolBox::getSelectedAccessibleChildCount( ) throw (RuntimeException)
845 OExternalLockGuard aGuard( this );
846 sal_Int32 nRet = 0;
847 for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
849 if ( isAccessibleChildSelected( i ) )
851 nRet = 1;
852 break; // a toolbox can only have (n)one selected child
855 return nRet;
857 // -----------------------------------------------------------------------------
858 Reference< XAccessible > VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
860 OExternalLockGuard aGuard( this );
861 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
862 throw IndexOutOfBoundsException();
863 Reference< XAccessible > xChild;
864 for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
866 if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
868 xChild = getAccessibleChild( i );
869 break;
872 return xChild;
874 // -----------------------------------------------------------------------------
875 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
877 OExternalLockGuard aGuard( this );
878 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
879 throw IndexOutOfBoundsException();
880 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
882 // -----------------------------------------------------------------------------