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 <standard/vclxaccessibletoolbox.hxx>
22 #include <standard/vclxaccessibletoolboxitem.hxx>
23 #include <toolkit/helper/convert.hxx>
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
27 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28 #include <o3tl/safeint.hxx>
29 #include <vcl/toolbox.hxx>
30 #include <vcl/vclevent.hxx>
31 #include <comphelper/accessiblecontexthelper.hxx>
32 #include <comphelper/accessiblewrapper.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/servicehelper.hxx>
35 #include <comphelper/types.hxx>
37 using namespace ::comphelper
;
38 using namespace ::com::sun::star
;
39 using namespace ::com::sun::star::uno
;
40 using namespace ::com::sun::star::lang
;
41 using namespace ::com::sun::star::accessibility
;
46 // = OToolBoxWindowItemContext
48 /** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window
50 class OToolBoxWindowItemContext final
: public OAccessibleContextWrapper
52 sal_Int32 m_nIndexInParent
;
54 OToolBoxWindowItemContext(sal_Int32 _nIndexInParent
,
55 const css::uno::Reference
< css::uno::XComponentContext
>& _rxContext
,
56 const css::uno::Reference
< css::accessibility::XAccessibleContext
>& _rxInnerAccessibleContext
,
57 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxOwningAccessible
,
58 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxParentAccessible
59 ) : OAccessibleContextWrapper(
61 _rxInnerAccessibleContext
,
64 ,m_nIndexInParent(_nIndexInParent
)
67 virtual sal_Int64 SAL_CALL
getAccessibleIndexInParent( ) override
;
71 sal_Int64 SAL_CALL
OToolBoxWindowItemContext::getAccessibleIndexInParent( )
73 ::osl::MutexGuard
aGuard( m_aMutex
);
74 return m_nIndexInParent
;
78 // = OToolBoxWindowItem
80 /** XAccessible implementation for a toolbox item which is represented by a VCL Window
82 class OToolBoxWindowItem
: public OAccessibleWrapper
85 sal_Int32 m_nIndexInParent
;
88 sal_Int32
getIndexInParent() const { return m_nIndexInParent
; }
89 void setIndexInParent( sal_Int32 _nNewIndex
) { m_nIndexInParent
= _nNewIndex
; }
92 OToolBoxWindowItem(sal_Int32 _nIndexInParent
,
93 const css::uno::Reference
< css::uno::XComponentContext
>& _rxContext
,
94 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxInnerAccessible
,
95 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxParentAccessible
96 ) : OAccessibleWrapper(
100 ,m_nIndexInParent(_nIndexInParent
)
105 // OAccessibleWrapper
106 virtual rtl::Reference
<OAccessibleContextWrapper
> createAccessibleContext(
107 const css::uno::Reference
< css::accessibility::XAccessibleContext
>& _rxInnerContext
111 rtl::Reference
<OAccessibleContextWrapper
> OToolBoxWindowItem::createAccessibleContext(
112 const Reference
< XAccessibleContext
>& _rxInnerContext
)
114 return new OToolBoxWindowItemContext( m_nIndexInParent
, getComponentContext(), _rxInnerContext
, this, getParent() );
118 // VCLXAccessibleToolBox
120 VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow
* pVCLXWindow
) :
122 ImplInheritanceHelper( pVCLXWindow
)
127 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
131 VCLXAccessibleToolBoxItem
* VCLXAccessibleToolBox::GetItem_Impl( ToolBox::ImplToolItems::size_type _nPos
)
133 VCLXAccessibleToolBoxItem
* pItem
= nullptr;
134 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
137 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
138 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
139 // returns only toolbox buttons, not windows
140 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is())
141 pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
147 void VCLXAccessibleToolBox::UpdateFocus_Impl()
149 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
153 // submit events only if toolbox has the focus to avoid sending events due to mouse move
154 bool bHasFocus
= false;
155 if ( pToolBox
->HasFocus() )
159 // check for subtoolbar, i.e. check if our parent is a toolbar
160 ToolBox
* pToolBoxParent
= dynamic_cast< ToolBox
* >( pToolBox
->GetParent() );
161 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
162 if ( pToolBoxParent
&& pToolBoxParent
->HasFocus() )
169 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
170 sal_uInt16 nFocusCount
= 0;
171 for ( const auto& [rPos
, rxChild
] : m_aAccessibleChildren
)
173 ToolBoxItemId nItemId
= pToolBox
->GetItemId( rPos
);
177 VCLXAccessibleToolBoxItem
* pItem
=
178 static_cast< VCLXAccessibleToolBoxItem
* >( rxChild
.get() );
179 if ( pItem
->HasFocus() && nItemId
!= nHighlightItemId
)
181 // reset the old focused item
182 pItem
->SetFocus( false );
185 if ( nItemId
== nHighlightItemId
)
187 // set the new focused item
188 pItem
->SetFocus( true );
192 // both items changed?
193 if ( nFocusCount
> 1 )
198 void VCLXAccessibleToolBox::ReleaseFocus_Impl( ToolBox::ImplToolItems::size_type _nPos
)
200 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
201 if ( pToolBox
) // #107124#, do not check for focus because this message is also handled in losefocus
203 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
204 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
205 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
207 VCLXAccessibleToolBoxItem
* pItem
=
208 static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
209 if ( pItem
->HasFocus() )
210 pItem
->SetFocus( false );
215 void VCLXAccessibleToolBox::UpdateChecked_Impl( ToolBox::ImplToolItems::size_type _nPos
)
217 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
221 ToolBoxItemId nFocusId
= pToolBox
->GetItemId( _nPos
);
222 VCLXAccessibleToolBoxItem
* pFocusItem
= nullptr;
224 for ( const auto& [rPos
, rxChild
] : m_aAccessibleChildren
)
226 ToolBoxItemId nItemId
= pToolBox
->GetItemId( rPos
);
228 VCLXAccessibleToolBoxItem
* pItem
=
229 static_cast< VCLXAccessibleToolBoxItem
* >( rxChild
.get() );
230 pItem
->SetChecked( pToolBox
->IsItemChecked( nItemId
) );
231 if ( nItemId
== nFocusId
)
234 //Solution:If the position is not a child item,the focus should not be called
235 if ( pFocusItem
&& _nPos
!= ToolBox::ITEM_NOTFOUND
)
236 pFocusItem
->SetFocus( true );
239 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( ToolBox::ImplToolItems::size_type _nPos
)
241 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
245 ToolBoxItemId nItemId
= pToolBox
->GetItemId( _nPos
);
247 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
248 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
249 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
251 VCLXAccessibleToolBoxItem
* pItem
=
252 static_cast< VCLXAccessibleToolBoxItem
* >( aIter
->second
.get() );
254 pItem
->SetIndeterminate( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
);
258 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator
const & _rMapPos
,
259 bool _bNotifyRemoval
)
261 Reference
< XAccessible
> xItemAcc( _rMapPos
->second
);
262 if ( !xItemAcc
.is() )
265 if ( _bNotifyRemoval
)
267 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any( xItemAcc
), Any() );
270 auto pWindowItem
= dynamic_cast<OToolBoxWindowItem
*>(xItemAcc
.get());
273 static_cast< VCLXAccessibleToolBoxItem
* >( xItemAcc
.get() )->ReleaseToolBox();
274 ::comphelper::disposeComponent( xItemAcc
);
278 Reference
< XAccessibleContext
> xContext( pWindowItem
->getContextNoCreate() );
279 ::comphelper::disposeComponent( xContext
);
283 void VCLXAccessibleToolBox::UpdateItem_Impl( ToolBox::ImplToolItems::size_type _nPos
)
285 if ( _nPos
< m_aAccessibleChildren
.size() )
287 UpdateAllItems_Impl();
291 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
295 // adjust the "index-in-parent"s
296 ToolBoxItemsMap::iterator aIndexAdjust
= m_aAccessibleChildren
.upper_bound( _nPos
);
297 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
298 while ( m_aAccessibleChildren
.end() != aIndexAdjust
)
300 Reference
< XAccessible
> xItemAcc( aIndexAdjust
->second
);
302 auto pWindowItem
= dynamic_cast<OToolBoxWindowItem
*>(xItemAcc
.get());
305 VCLXAccessibleToolBoxItem
* pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( xItemAcc
.get() );
308 sal_Int32 nIndex
= pItem
->getIndexInParent( );
310 pItem
->setIndexInParent( nIndex
);
315 sal_Int32 nIndex
= pWindowItem
->getIndexInParent( );
317 pWindowItem
->setIndexInParent( nIndex
);
323 // TODO: we should make this dependent on the existence of event listeners
324 // with the current implementation, we always create accessible object
325 Any
aNewChild( getAccessibleChild( static_cast<sal_Int64
>(_nPos
) ) );
326 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
327 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewChild
);
330 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
332 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
336 // deregister the old items
337 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
338 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
340 implReleaseToolboxItem( aIter
, true );
342 m_aAccessibleChildren
.clear();
344 // register the new items
345 ToolBox::ImplToolItems::size_type i
, nCount
= pToolBox
->GetItemCount();
346 for ( i
= 0; i
< nCount
; ++i
)
349 aNewValue
<<= getAccessibleChild(i
);
350 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
354 void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( vcl::Window
* pWindow
, bool bOpen
)
356 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
357 if( !(pWindow
&& pToolBox
) )
360 const ToolBoxItemId nDownItem
= pToolBox
->GetDownItemId();
362 // No item is currently in down state.
363 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
366 Reference
< XAccessible
> xChild( pWindow
->GetAccessible() );
369 Reference
< XAccessible
> xChildItem( getAccessibleChild(pToolBox
->GetItemPos(nDownItem
)));
370 VCLXAccessibleToolBoxItem
* pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( xChildItem
.get() );
372 pItem
->SetChild( xChild
);
373 pItem
->NotifyChildEvent( xChild
, bOpen
);
377 void VCLXAccessibleToolBox::UpdateItemName_Impl( ToolBox::ImplToolItems::size_type _nPos
)
379 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
);
381 pItem
->NameChanged();
384 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( ToolBox::ImplToolItems::size_type _nPos
)
386 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
);
388 pItem
->ToggleEnableState();
391 void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent
& rVclWindowEvent
)
393 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
394 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
397 && pToolBox
== pChildWindow
->GetParent()
398 && pChildWindow
->GetType() == WindowType::TOOLBOX
) )
401 const ToolBoxItemId
nCurItemId( pToolBox
->GetCurItemId() );
403 // No item is currently active (might happen when opening the overflow popup).
404 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
407 ToolBox::ImplToolItems::size_type nIndex
= pToolBox
->GetItemPos( nCurItemId
);
408 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
411 Reference
< XAccessible
> xChild
= pChildWindow
->GetAccessible();
412 VCLXAccessibleToolBoxItem
* pItem
=
413 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
414 pItem
->SetChild( xChild
);
415 pItem
->NotifyChildEvent( xChild
, true/*_bShow*/ );
419 void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox
* _pSubToolBox
)
421 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
425 ToolBox::ImplToolItems::size_type nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
426 if ( nIndex
== ToolBox::ITEM_NOTFOUND
)
429 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
433 Reference
< XAccessible
> xChild
= _pSubToolBox
->GetAccessible();
434 VCLXAccessibleToolBoxItem
* pItem
=
435 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
436 if ( pItem
->GetChild() == xChild
)
438 pItem
->SetChild( Reference
< XAccessible
>() );
439 pItem
->NotifyChildEvent( xChild
, false );
443 void VCLXAccessibleToolBox::FillAccessibleStateSet( sal_Int64
& rStateSet
)
445 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
447 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
450 rStateSet
|= AccessibleStateType::FOCUSABLE
;
451 if ( pToolBox
->IsHorizontal() )
452 rStateSet
|= AccessibleStateType::HORIZONTAL
;
454 rStateSet
|= AccessibleStateType::VERTICAL
;
458 void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
460 // to prevent an early release of the toolbox (VclEventId::ObjectDying)
461 Reference
< XAccessibleContext
> xHoldAlive
= this;
463 switch ( rVclWindowEvent
.GetId() )
465 case VclEventId::ToolboxClick
:
466 case VclEventId::ToolboxSelect
:
468 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
469 if ( rVclWindowEvent
.GetData() )
471 UpdateChecked_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
472 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
474 else if( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) != ToolBox::ITEM_NOTFOUND
)
476 UpdateChecked_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
477 UpdateIndeterminate_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
481 case VclEventId::ToolboxDoubleClick
:
482 case VclEventId::ToolboxActivate
:
483 case VclEventId::ToolboxDeactivate
:
484 //case VclEventId::ToolboxSelect:
487 case VclEventId::ToolboxItemUpdated
:
489 if ( rVclWindowEvent
.GetData() )
491 UpdateChecked_Impl( ToolBox::ITEM_NOTFOUND
);
492 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
497 case VclEventId::ToolboxHighlight
:
501 case VclEventId::ToolboxHighlightOff
:
502 ReleaseFocus_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
505 case VclEventId::ToolboxItemAdded
:
506 UpdateItem_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
509 case VclEventId::ToolboxItemRemoved
:
510 case VclEventId::ToolboxAllItemsChanged
:
512 UpdateAllItems_Impl();
516 case VclEventId::ToolboxItemWindowChanged
:
518 auto nPos
= static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
519 ToolBoxItemsMap::iterator
aAccessiblePos( m_aAccessibleChildren
.find( nPos
) );
520 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
521 if ( m_aAccessibleChildren
.end() != aAccessiblePos
)
523 implReleaseToolboxItem( aAccessiblePos
, false );
524 m_aAccessibleChildren
.erase (aAccessiblePos
);
528 aNewValue
<<= getAccessibleChild(nPos
);
529 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
532 case VclEventId::ToolboxItemTextChanged
:
533 UpdateItemName_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
536 case VclEventId::ToolboxItemEnabled
:
537 case VclEventId::ToolboxItemDisabled
:
539 UpdateItemEnabled_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
543 case VclEventId::DropdownOpen
:
544 case VclEventId::DropdownClose
:
546 UpdateCustomPopupItemp_Impl( static_cast< vcl::Window
* >( rVclWindowEvent
.GetData() ), rVclWindowEvent
.GetId() == VclEventId::DropdownOpen
);
550 case VclEventId::ObjectDying
:
552 // if this toolbox is a subtoolbox, we have to release it from its parent
553 VclPtr
< vcl::Window
> pWin
= GetAs
< vcl::Window
>();
554 if ( pWin
&& pWin
->GetParent() &&
555 pWin
->GetParent()->GetType() == WindowType::TOOLBOX
)
557 auto pParentAccContext
= pWin
->GetParent()->GetAccessible()->getAccessibleContext();
558 VCLXAccessibleToolBox
* pParent
= static_cast< VCLXAccessibleToolBox
* >( pParentAccContext
.get() );
560 pParent
->ReleaseSubToolBox(static_cast<ToolBox
*>(pWin
.get()));
564 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
565 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
567 implReleaseToolboxItem( aIter
, false );
569 m_aAccessibleChildren
.clear();
571 [[fallthrough
]]; // call base class
575 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
579 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
581 switch ( rVclWindowEvent
.GetId() )
583 case VclEventId::WindowShow
: // send create on show for direct accessible children
585 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
587 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), Any(xReturn
) );
589 HandleSubToolBarEvent( rVclWindowEvent
);
594 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
600 void SAL_CALL
VCLXAccessibleToolBox::disposing()
602 VCLXAccessibleComponent::disposing();
605 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
606 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
608 implReleaseToolboxItem( aIter
, false );
610 m_aAccessibleChildren
.clear();
614 OUString
VCLXAccessibleToolBox::getImplementationName()
616 return "com.sun.star.comp.toolkit.AccessibleToolBox";
619 Sequence
< OUString
> VCLXAccessibleToolBox::getSupportedServiceNames()
621 return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(),
622 Sequence
<OUString
>{"com.sun.star.accessibility.AccessibleToolBox"});
625 // XAccessibleContext
626 sal_Int64 SAL_CALL
VCLXAccessibleToolBox::getAccessibleChildCount( )
628 comphelper::OExternalLockGuard
aGuard( this );
629 return implGetAccessibleChildCount();
632 sal_Int64
VCLXAccessibleToolBox::implGetAccessibleChildCount( )
634 sal_Int64 nCount
= 0;
635 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
637 nCount
= pToolBox
->GetItemCount();
642 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleChild( sal_Int64 i
)
644 comphelper::OExternalLockGuard
aGuard( this );
646 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
647 if ( (!pToolBox
) || i
< 0 || o3tl::make_unsigned(i
) >= pToolBox
->GetItemCount() )
648 throw IndexOutOfBoundsException();
650 Reference
< XAccessible
> xChild
;
651 // search for the child
652 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find(i
);
653 if ( m_aAccessibleChildren
.end() == aIter
)
655 ToolBoxItemId nItemId
= pToolBox
->GetItemId( i
);
656 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
657 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
658 // not found -> create a new child
659 rtl::Reference
<VCLXAccessibleToolBoxItem
> pChild
= new VCLXAccessibleToolBoxItem( pToolBox
, i
);
660 Reference
< XAccessible
> xParent
= pChild
;
663 xChild
= new OToolBoxWindowItem(0,::comphelper::getProcessComponentContext(),pItemWindow
->GetAccessible(),xParent
);
664 pItemWindow
->SetAccessible(xChild
);
665 pChild
->SetChild( xChild
);
668 if ( nHighlightItemId
> ToolBoxItemId(0) && nItemId
== nHighlightItemId
)
669 pChild
->SetFocus( true );
670 if ( pToolBox
->IsItemChecked( nItemId
) )
671 pChild
->SetChecked( true );
672 if ( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
)
673 pChild
->SetIndeterminate( true );
674 m_aAccessibleChildren
.emplace( i
, xChild
);
679 xChild
= aIter
->second
;
684 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point
& _rPoint
)
686 comphelper::OExternalLockGuard
aGuard( this );
688 Reference
< XAccessible
> xAccessible
;
689 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
692 ToolBox::ImplToolItems::size_type nItemPos
= pToolBox
->GetItemPos( VCLPoint( _rPoint
) );
693 if ( nItemPos
!= ToolBox::ITEM_NOTFOUND
)
694 xAccessible
= getAccessibleChild( nItemPos
);
700 Reference
< XAccessible
> VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent
& rVclWindowEvent
)
702 Reference
< XAccessible
> xReturn
;
703 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
704 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
705 if ( pChildWindow
&& pToolBox
)
707 ToolBox::ImplToolItems::size_type nCount
= pToolBox
->GetItemCount();
708 for (ToolBox::ImplToolItems::size_type i
= 0 ; i
< nCount
&& !xReturn
.is() ; ++i
)
710 ToolBoxItemId nItemId
= pToolBox
->GetItemId( i
);
711 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
712 if ( pItemWindow
== pChildWindow
)
713 xReturn
= getAccessibleChild(i
);
719 Reference
< XAccessible
> VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
721 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
724 xReturn
= VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent
);
728 // XAccessibleSelection
729 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int64 nChildIndex
)
731 OExternalLockGuard
aGuard( this );
733 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
734 if ( (!pToolBox
) || nChildIndex
< 0 || o3tl::make_unsigned(nChildIndex
) >= pToolBox
->GetItemCount() )
735 throw IndexOutOfBoundsException();
737 pToolBox
->ChangeHighlight( nChildIndex
);
740 sal_Bool
VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int64 nChildIndex
)
742 OExternalLockGuard
aGuard( this );
743 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
744 if ( (!pToolBox
) || nChildIndex
< 0 || o3tl::make_unsigned(nChildIndex
) >= pToolBox
->GetItemCount() )
745 throw IndexOutOfBoundsException();
747 if ( pToolBox
->GetHighlightItemId() == pToolBox
->GetItemId( nChildIndex
) )
753 void VCLXAccessibleToolBox::clearAccessibleSelection( )
755 OExternalLockGuard
aGuard( this );
756 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
757 pToolBox
-> LoseFocus();
760 void VCLXAccessibleToolBox::selectAllAccessibleChildren( )
762 OExternalLockGuard
aGuard( this );
763 // intentionally empty. makes no sense for a toolbox
766 sal_Int64
VCLXAccessibleToolBox::getSelectedAccessibleChildCount( )
768 OExternalLockGuard
aGuard( this );
771 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
774 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
775 for ( size_t i
= 0, nCount
= pToolBox
->GetItemCount(); i
< nCount
; i
++ )
777 if ( nHighlightItemId
== pToolBox
->GetItemId( i
) )
780 break; // a toolbox can only have (n)one selected child
788 Reference
< XAccessible
> VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex
)
790 OExternalLockGuard
aGuard( this );
791 if ( nSelectedChildIndex
!= 0 )
792 throw IndexOutOfBoundsException();
794 Reference
< XAccessible
> xChild
;
795 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
798 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
799 for (ToolBox::ImplToolItems::size_type i
= 0, nCount
= pToolBox
->GetItemCount(); i
< nCount
; i
++ )
801 if ( nHighlightItemId
== pToolBox
->GetItemId( i
) )
803 xChild
= getAccessibleChild( i
);
810 throw IndexOutOfBoundsException();
815 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int64 nChildIndex
)
817 OExternalLockGuard
aGuard( this );
818 if ( nChildIndex
< 0 || nChildIndex
>= implGetAccessibleChildCount() )
819 throw IndexOutOfBoundsException();
820 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
823 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */