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
;
42 // = OToolBoxWindowItemContext
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
, std::exception
) SAL_OVERRIDE
;
67 sal_Int32 SAL_CALL
OToolBoxWindowItemContext::getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
)
69 ::osl::MutexGuard
aGuard( m_aMutex
);
70 return m_nIndexInParent
;
74 // = OToolBoxWindowItem
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 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
, std::exception
) SAL_OVERRIDE
;
119 static Sequence
< sal_Int8
> getUnoTunnelImplementationId();
122 IMPLEMENT_FORWARD_XINTERFACE2( OToolBoxWindowItem
, OAccessibleWrapper
, OToolBoxWindowItem_Base
)
123 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OToolBoxWindowItem
, OAccessibleWrapper
, OToolBoxWindowItem_Base
)
125 OAccessibleContextWrapper
* OToolBoxWindowItem::createAccessibleContext(
126 const Reference
< XAccessibleContext
>& _rxInnerContext
)
128 return new OToolBoxWindowItemContext( m_nIndexInParent
, getComponentContext(), _rxInnerContext
, this, getParent() );
131 bool OToolBoxWindowItem::isWindowItem( const Reference
< XAccessible
>& _rxAcc
, OToolBoxWindowItem
** /* [out] */ _ppImplementation
)
133 OToolBoxWindowItem
* pImplementation
= NULL
;
135 Reference
< XUnoTunnel
> xTunnel( _rxAcc
, UNO_QUERY
);
137 pImplementation
= reinterpret_cast< OToolBoxWindowItem
* >( xTunnel
->getSomething( getUnoTunnelImplementationId() ) );
139 if ( _ppImplementation
)
140 *_ppImplementation
= pImplementation
;
142 return NULL
!= pImplementation
;
145 Sequence
< sal_Int8
> OToolBoxWindowItem::getUnoTunnelImplementationId()
147 static ::cppu::OImplementationId
* pId
= 0;
150 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
153 static ::cppu::OImplementationId aId
;
157 return pId
->getImplementationId();
160 sal_Int64 SAL_CALL
OToolBoxWindowItem::getSomething( const Sequence
< sal_Int8
>& _rId
) throw (RuntimeException
, std::exception
)
162 if ( ( 16 == _rId
.getLength() )
163 && ( 0 == memcmp( getUnoTunnelImplementationId().getConstArray(), _rId
.getConstArray(), 16 ) )
165 return reinterpret_cast< sal_Int64
>( this );
171 // VCLXAccessibleToolBox
173 VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow
* pVCLXWindow
) :
175 VCLXAccessibleComponent( pVCLXWindow
)
180 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
184 VCLXAccessibleToolBoxItem
* VCLXAccessibleToolBox::GetItem_Impl( sal_Int32 _nPos
, bool _bMustHaveFocus
)
186 VCLXAccessibleToolBoxItem
* pItem
= NULL
;
187 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
188 if ( pToolBox
&& ( !_bMustHaveFocus
|| pToolBox
->HasFocus() ) )
190 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
191 // returns only toolbox buttons, not windows
192 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is())
193 pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
199 void VCLXAccessibleToolBox::UpdateFocus_Impl()
201 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
205 // submit events only if toolbox has the focus to avoid sending events due to mouse move
206 bool bHasFocus
= false;
207 if ( pToolBox
->HasFocus() )
211 // check for subtoolbar, i.e. check if our parent is a toolbar
212 ToolBox
* pToolBoxParent
= dynamic_cast< ToolBox
* >( pToolBox
->GetParent() );
213 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
214 if ( pToolBoxParent
&& pToolBoxParent
->HasFocus() )
220 sal_uInt16 nHighlightItemId
= pToolBox
->GetHighlightItemId();
221 sal_uInt16 nFocusCount
= 0;
222 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
223 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
225 sal_uInt16 nItemId
= pToolBox
->GetItemId( (sal_uInt16
)aIter
->first
);
227 if ( aIter
->second
.is() )
229 VCLXAccessibleToolBoxItem
* pItem
=
230 static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
231 if ( pItem
->HasFocus() && nItemId
!= nHighlightItemId
)
233 // reset the old focused item
234 pItem
->SetFocus( false );
237 if ( nItemId
== nHighlightItemId
)
239 // set the new focused item
240 pItem
->SetFocus( true );
244 // both items changed?
245 if ( nFocusCount
> 1 )
251 void VCLXAccessibleToolBox::ReleaseFocus_Impl( sal_Int32 _nPos
)
253 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
254 if ( pToolBox
) // #107124#, do not check for focus because this message is also handled in losefocus
256 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
257 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
259 VCLXAccessibleToolBoxItem
* pItem
=
260 static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
261 if ( pItem
->HasFocus() )
262 pItem
->SetFocus( false );
267 void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 _nPos
)
269 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
272 sal_uInt16 nFocusId
= pToolBox
->GetItemId( (sal_uInt16
)_nPos
);
273 VCLXAccessibleToolBoxItem
* pFocusItem
= NULL
;
275 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
276 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
278 sal_uInt16 nItemId
= pToolBox
->GetItemId( (sal_uInt16
)aIter
->first
);
280 VCLXAccessibleToolBoxItem
* pItem
=
281 static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
282 pItem
->SetChecked( pToolBox
->IsItemChecked( nItemId
) );
283 if ( nItemId
== nFocusId
)
286 //Solution:If the position is not a child item,the focus should not be called
287 if ( pFocusItem
&& (sal_uInt16
)_nPos
!= TOOLBOX_ITEM_NOTFOUND
)
288 pFocusItem
->SetFocus( true );
292 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( sal_Int32 _nPos
)
294 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
297 sal_uInt16 nItemId
= pToolBox
->GetItemId( (sal_uInt16
)_nPos
);
299 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
300 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
302 VCLXAccessibleToolBoxItem
* pItem
=
303 static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
305 pItem
->SetIndeterminate( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
);
310 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator
& _rMapPos
,
311 bool _bNotifyRemoval
, bool _bDispose
)
313 Reference
< XAccessible
> xItemAcc( _rMapPos
->second
);
314 if ( !xItemAcc
.is() )
317 if ( _bNotifyRemoval
)
319 NotifyAccessibleEvent( AccessibleEventId::CHILD
, makeAny( xItemAcc
), Any() );
322 OToolBoxWindowItem
* pWindowItem
= NULL
;
323 if ( !OToolBoxWindowItem::isWindowItem( xItemAcc
, &pWindowItem
) )
325 static_cast< VCLXAccessibleToolBoxItem
* >( xItemAcc
.get() )->ReleaseToolBox();
327 ::comphelper::disposeComponent( xItemAcc
);
335 Reference
< XAccessibleContext
> xContext( pWindowItem
->getContextNoCreate() );
336 ::comphelper::disposeComponent( xContext
);
342 void VCLXAccessibleToolBox::UpdateItem_Impl( sal_Int32 _nPos
, bool _bItemAdded
)
344 if ( _nPos
< sal_Int32( m_aAccessibleChildren
.size() ) )
346 UpdateAllItems_Impl();
350 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
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
);
404 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
406 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
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 void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( vcl::Window
* pWindow
, bool bOpen
)
430 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
431 if( pWindow
&& pToolBox
)
433 const sal_uInt16 nDownItem
= pToolBox
->GetDownItemId();
435 // Items with ItemId == 0 are not allowed in ToolBox, which means that currently no item is in down state.
436 // Moreover, running GetItemPos with 0 could find a separator item if there is any.
439 Reference
< XAccessible
> xChild( pWindow
->GetAccessible() );
442 Reference
< XAccessible
> xChildItem( getAccessibleChild( static_cast< sal_Int32
>( pToolBox
->GetItemPos( nDownItem
) ) ) );
443 VCLXAccessibleToolBoxItem
* pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( xChildItem
.get() );
445 pItem
->SetChild( xChild
);
446 pItem
->NotifyChildEvent( xChild
, bOpen
);
451 void VCLXAccessibleToolBox::UpdateItemName_Impl( sal_Int32 _nPos
)
453 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
, false );
455 pItem
->NameChanged();
458 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( sal_Int32 _nPos
)
460 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
, false );
462 pItem
->ToggleEnableState();
465 void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent
& rVclWindowEvent
, bool _bShow
)
467 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
468 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
471 && pToolBox
== pChildWindow
->GetParent()
472 && pChildWindow
->GetType() == WINDOW_TOOLBOX
)
474 sal_Int32 nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
475 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
478 Reference
< XAccessible
> xChild
= pChildWindow
->GetAccessible();
479 VCLXAccessibleToolBoxItem
* pItem
=
480 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
481 pItem
->SetChild( xChild
);
482 pItem
->NotifyChildEvent( xChild
, _bShow
);
487 void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox
* _pSubToolBox
)
489 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
493 sal_Int32 nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
494 if ( nIndex
== SAL_MAX_UINT16
)
497 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
501 Reference
< XAccessible
> xChild
= _pSubToolBox
->GetAccessible();
502 VCLXAccessibleToolBoxItem
* pItem
=
503 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
504 if ( pItem
->GetChild() == xChild
)
506 pItem
->SetChild( Reference
< XAccessible
>() );
507 pItem
->NotifyChildEvent( xChild
, false );
511 void VCLXAccessibleToolBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
513 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
515 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
518 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
519 if ( pToolBox
->IsHorizontal() )
520 rStateSet
.AddState( AccessibleStateType::HORIZONTAL
);
522 rStateSet
.AddState( AccessibleStateType::VERTICAL
);
526 void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
528 // to prevent an early release of the toolbox (VCLEVENT_OBJECT_DYING)
529 Reference
< XAccessibleContext
> xTemp
= this;
531 switch ( rVclWindowEvent
.GetId() )
533 case VCLEVENT_TOOLBOX_CLICK
:
534 case VCLEVENT_TOOLBOX_SELECT
:
536 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
537 if ( rVclWindowEvent
.GetData() )
539 UpdateChecked_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()) );
540 UpdateIndeterminate_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()) );
542 else if( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) != TOOLBOX_ITEM_NOTFOUND
)
544 UpdateChecked_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
545 UpdateIndeterminate_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
549 case VCLEVENT_TOOLBOX_DOUBLECLICK
:
550 case VCLEVENT_TOOLBOX_ACTIVATE
:
551 case VCLEVENT_TOOLBOX_DEACTIVATE
:
552 //case VCLEVENT_TOOLBOX_SELECT:
555 case VCLEVENT_TOOLBOX_ITEMUPDATED
:
557 if ( rVclWindowEvent
.GetData() )
559 UpdateChecked_Impl( TOOLBOX_ITEM_NOTFOUND
);
560 UpdateIndeterminate_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()) );
565 case VCLEVENT_TOOLBOX_HIGHLIGHT
:
569 case VCLEVENT_TOOLBOX_HIGHLIGHTOFF
:
570 ReleaseFocus_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()) );
573 case VCLEVENT_TOOLBOX_ITEMADDED
:
574 UpdateItem_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()), true );
577 case VCLEVENT_TOOLBOX_ITEMREMOVED
:
578 case VCLEVENT_TOOLBOX_ALLITEMSCHANGED
:
580 UpdateAllItems_Impl();
584 case VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED
:
586 sal_Int32 nPos
= (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData());
587 ToolBoxItemsMap::iterator
aAccessiblePos( m_aAccessibleChildren
.find( nPos
) );
588 if ( m_aAccessibleChildren
.end() != aAccessiblePos
)
590 implReleaseToolboxItem( aAccessiblePos
, false, true );
591 m_aAccessibleChildren
.erase (aAccessiblePos
);
595 aNewValue
<<= getAccessibleChild(nPos
);
596 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
599 case VCLEVENT_TOOLBOX_ITEMTEXTCHANGED
:
600 UpdateItemName_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()) );
603 case VCLEVENT_TOOLBOX_ITEMENABLED
:
604 case VCLEVENT_TOOLBOX_ITEMDISABLED
:
606 UpdateItemEnabled_Impl( (sal_Int32
)reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()) );
610 case VCLEVENT_DROPDOWN_OPEN
:
611 case VCLEVENT_DROPDOWN_CLOSE
:
613 UpdateCustomPopupItemp_Impl( static_cast< vcl::Window
* >( rVclWindowEvent
.GetData() ), rVclWindowEvent
.GetId() == VCLEVENT_DROPDOWN_OPEN
);
617 case VCLEVENT_OBJECT_DYING
:
619 // if this toolbox is a subtoolbox, we have to relese it from its parent
620 VclPtr
< vcl::Window
> pWin
= GetAs
< vcl::Window
>();
621 if ( pWin
&& pWin
->GetParent() &&
622 pWin
->GetParent()->GetType() == WINDOW_TOOLBOX
)
624 VCLXAccessibleToolBox
* pParent
= static_cast< VCLXAccessibleToolBox
* >(
625 pWin
->GetParent()->GetAccessible()->getAccessibleContext().get() );
627 pParent
->ReleaseSubToolBox(static_cast<ToolBox
*>(pWin
.get()));
631 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
632 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
634 implReleaseToolboxItem( aIter
, false, true );
636 m_aAccessibleChildren
.clear();
638 //!!! no break to call base class
642 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
646 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
648 switch ( rVclWindowEvent
.GetId() )
650 case VCLEVENT_WINDOW_SHOW
: // send create on show for direct accessible children
652 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
654 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), makeAny(xReturn
) );
656 HandleSubToolBarEvent( rVclWindowEvent
, true );
661 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
667 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox
, VCLXAccessibleComponent
, VCLXAccessibleToolBox_BASE
)
670 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox
, VCLXAccessibleComponent
, VCLXAccessibleToolBox_BASE
)
673 void SAL_CALL
VCLXAccessibleToolBox::disposing()
675 VCLXAccessibleComponent::disposing();
678 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
679 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
681 implReleaseToolboxItem( aIter
, false, true );
683 m_aAccessibleChildren
.clear();
687 OUString
VCLXAccessibleToolBox::getImplementationName() throw (RuntimeException
, std::exception
)
689 return OUString( "com.sun.star.comp.toolkit.AccessibleToolBox" );
692 Sequence
< OUString
> VCLXAccessibleToolBox::getSupportedServiceNames() throw (RuntimeException
, std::exception
)
694 Sequence
< OUString
> aNames
= VCLXAccessibleComponent::getSupportedServiceNames();
695 sal_Int32 nLength
= aNames
.getLength();
696 aNames
.realloc( nLength
+ 1 );
697 aNames
[nLength
] = "com.sun.star.accessibility.AccessibleToolBox";
701 // XAccessibleContext
702 sal_Int32 SAL_CALL
VCLXAccessibleToolBox::getAccessibleChildCount( ) throw (RuntimeException
, std::exception
)
704 comphelper::OExternalLockGuard
aGuard( this );
706 sal_Int32 nCount
= 0;
707 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
709 nCount
= pToolBox
->GetItemCount();
714 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
716 if ( i
< 0 || i
>= getAccessibleChildCount() )
717 throw IndexOutOfBoundsException();
719 comphelper::OExternalLockGuard
aGuard( this );
721 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
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 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
732 // not found -> create a new child
733 VCLXAccessibleToolBoxItem
* pChild
= new VCLXAccessibleToolBoxItem( pToolBox
, i
);
734 Reference
< XAccessible
> xParent
= pChild
;
737 xChild
= new OToolBoxWindowItem(0,::comphelper::getProcessComponentContext(),pItemWindow
->GetAccessible(),xParent
);
738 pItemWindow
->SetAccessible(xChild
);
739 pChild
->SetChild( xChild
);
742 if ( nHighlightItemId
> 0 && nItemId
== nHighlightItemId
)
743 pChild
->SetFocus( true );
744 if ( pToolBox
->IsItemChecked( nItemId
) )
745 pChild
->SetChecked( true );
746 if ( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
)
747 pChild
->SetIndeterminate( true );
748 m_aAccessibleChildren
.insert( ToolBoxItemsMap::value_type( i
, xChild
) );
753 xChild
= aIter
->second
;
761 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point
& _rPoint
) throw (RuntimeException
, std::exception
)
763 comphelper::OExternalLockGuard
aGuard( this );
765 Reference
< XAccessible
> xAccessible
;
766 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
769 sal_uInt16 nItemPos
= pToolBox
->GetItemPos( VCLPoint( _rPoint
) );
770 if ( nItemPos
!= TOOLBOX_ITEM_NOTFOUND
)
771 xAccessible
= getAccessibleChild( nItemPos
);
777 Reference
< XAccessible
> VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent
& rVclWindowEvent
)
779 Reference
< XAccessible
> xReturn
;
780 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
781 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
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 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
789 if ( pItemWindow
== pChildWindow
)
790 xReturn
= getAccessibleChild(i
);
796 Reference
< XAccessible
> VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
798 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
801 xReturn
= VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent
);
805 // XAccessibleSelection
806 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
808 OExternalLockGuard
aGuard( this );
809 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
810 throw IndexOutOfBoundsException();
811 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
812 sal_uInt16 nPos
= static_cast < sal_uInt16
> (nChildIndex
);
813 pToolBox
->ChangeHighlight( nPos
);
816 sal_Bool
VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
818 OExternalLockGuard
aGuard( this );
819 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
820 throw IndexOutOfBoundsException();
821 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
822 sal_uInt16 nPos
= static_cast < sal_uInt16
> (nChildIndex
);
823 if ( pToolBox
&& pToolBox
->GetHighlightItemId() == pToolBox
->GetItemId( nPos
) )
829 void VCLXAccessibleToolBox::clearAccessibleSelection( ) throw (RuntimeException
, std::exception
)
831 OExternalLockGuard
aGuard( this );
832 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
833 pToolBox
-> LoseFocus();
836 void VCLXAccessibleToolBox::selectAllAccessibleChildren( ) throw (RuntimeException
, std::exception
)
838 OExternalLockGuard
aGuard( this );
839 // intentionally empty. makes no sense for a toolbox
842 sal_Int32
VCLXAccessibleToolBox::getSelectedAccessibleChildCount( ) throw (RuntimeException
, std::exception
)
844 OExternalLockGuard
aGuard( this );
846 for ( sal_Int32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; i
++ )
848 if ( isAccessibleChildSelected( i
) )
851 break; // a toolbox can only have (n)one selected child
857 Reference
< XAccessible
> VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
859 OExternalLockGuard
aGuard( this );
860 if ( nSelectedChildIndex
< 0 || nSelectedChildIndex
>= getSelectedAccessibleChildCount() )
861 throw IndexOutOfBoundsException();
862 Reference
< XAccessible
> xChild
;
863 for ( sal_Int32 i
= 0, j
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; i
++ )
865 if ( isAccessibleChildSelected( i
) && ( j
++ == nSelectedChildIndex
) )
867 xChild
= getAccessibleChild( i
);
874 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
876 OExternalLockGuard
aGuard( this );
877 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
878 throw IndexOutOfBoundsException();
879 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
882 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */