1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
;
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
;
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(
57 _rxInnerAccessibleContext
,
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
86 sal_Int32 m_nIndexInParent
;
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
);
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(
103 ,m_nIndexInParent(_nIndexInParent
)
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
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
);
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;
154 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
157 static ::cppu::OImplementationId 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 );
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() );
204 // -----------------------------------------------------------------------------
206 void VCLXAccessibleToolBox::UpdateFocus_Impl()
208 ToolBox
* pToolBox
= static_cast< ToolBox
* >( GetWindow() );
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
;
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
;
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
);
244 if ( nItemId
== nHighlightItemId
)
246 // set the new focused item
247 pItem
->SetFocus( sal_True
);
251 // both items changed?
252 if ( nFocusCount
> 1 )
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() );
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() );
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() );
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() )
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();
326 ::comphelper::disposeComponent( xItemAcc
);
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();
350 ToolBox
* pToolBox
= static_cast< ToolBox
* >( GetWindow() );
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() );
376 sal_Int32 nIndex
= pItem
->getIndexInParent( );
377 nIndex
+= (_bItemAdded
? +1 : -1);
378 pItem
->setIndexInParent( nIndex
);
385 sal_Int32 nIndex
= pWindowItem
->getIndexInParent( );
386 nIndex
+= (_bItemAdded
? +1 : -1);
387 pWindowItem
->setIndexInParent( nIndex
);
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() );
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
)
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() );
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 );
452 pItem
->NameChanged();
454 // -----------------------------------------------------------------------------
455 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( sal_Int32 _nPos
)
457 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
, false );
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() );
468 && pToolBox
== pChildWindow
->GetParent()
469 && pChildWindow
->GetType() == WINDOW_TOOLBOX
)
471 sal_Int32 nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
472 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
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() );
489 sal_Int32 nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
490 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
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() );
512 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
513 if ( pToolBox
->IsHorizontal() )
514 rStateSet
.AddState( AccessibleStateType::HORIZONTAL
);
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() );
536 case VCLEVENT_TOOLBOX_DOUBLECLICK
:
537 case VCLEVENT_TOOLBOX_ACTIVATE
:
538 case VCLEVENT_TOOLBOX_DEACTIVATE
:
539 case VCLEVENT_TOOLBOX_SELECT
:
542 case VCLEVENT_TOOLBOX_HIGHLIGHT
:
546 case VCLEVENT_TOOLBOX_HIGHLIGHTOFF
:
547 ReleaseFocus_Impl( (sal_Int32
)(sal_IntPtr
)rVclWindowEvent
.GetData() );
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
);
555 case VCLEVENT_TOOLBOX_ITEMREMOVED
:
556 case VCLEVENT_TOOLBOX_ALLITEMSCHANGED
:
558 UpdateAllItems_Impl();
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
);
573 aNewValue
<<= getAccessibleChild(nPos
);
574 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
577 case VCLEVENT_TOOLBOX_ITEMTEXTCHANGED
:
578 UpdateItemName_Impl( (sal_Int32
)(sal_IntPtr
)rVclWindowEvent
.GetData() );
581 case VCLEVENT_TOOLBOX_ITEMENABLED
:
582 case VCLEVENT_TOOLBOX_ITEMDISABLED
:
584 UpdateItemEnabled_Impl( (sal_Int32
)(sal_IntPtr
)rVclWindowEvent
.GetData() );
588 case VCLEVENT_DROPDOWN_OPEN
:
589 case VCLEVENT_DROPDOWN_CLOSE
:
591 UpdateCustomPopupItemp_Impl( static_cast< Window
* >( rVclWindowEvent
.GetData() ), rVclWindowEvent
.GetId() == VCLEVENT_DROPDOWN_OPEN
);
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() );
605 pParent
->ReleaseSubToolBox( pToolBox
);
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
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
);
632 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), makeAny(xReturn
) );
634 HandleSubToolBarEvent( rVclWindowEvent
, true );
639 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
643 // -----------------------------------------------------------------------------
645 // -----------------------------------------------------------------------------
646 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox
, VCLXAccessibleComponent
, VCLXAccessibleToolBox_BASE
)
647 // -----------------------------------------------------------------------------
649 // -----------------------------------------------------------------------------
650 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox
, VCLXAccessibleComponent
, VCLXAccessibleToolBox_BASE
)
651 // -----------------------------------------------------------------------------
653 // -----------------------------------------------------------------------------
654 void SAL_CALL
VCLXAccessibleToolBox::disposing()
656 VCLXAccessibleComponent::disposing();
659 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
660 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
662 implReleaseToolboxItem( aIter
, false, true );
664 m_aAccessibleChildren
.clear();
666 // -----------------------------------------------------------------------------
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";
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() );
692 nCount
= pToolBox
->GetItemCount();
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() );
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
;
720 xChild
= new OToolBoxWindowItem(0,::comphelper::getProcessComponentContext(),pItemWindow
->GetAccessible(),xParent
);
721 pItemWindow
->SetAccessible(xChild
);
722 pChild
->SetChild( xChild
);
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
) );
736 xChild
= aIter
->second
;
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() );
752 sal_uInt16 nItemPos
= pToolBox
->GetItemPos( VCLPoint( _rPoint
) );
753 if ( nItemPos
!= TOOLBOX_ITEM_NOTFOUND
)
754 xAccessible
= getAccessibleChild( nItemPos
);
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
);
778 // -----------------------------------------------------------------------------
779 Reference
< XAccessible
> VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
781 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
784 xReturn
= VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent
);
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
) )
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 );
830 for ( sal_Int32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; i
++ )
832 if ( isAccessibleChildSelected( i
) )
835 break; // a toolbox can only have (n)one selected child
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
);
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: */