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/vclunohelper.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 return m_nIndexInParent
;
77 // = OToolBoxWindowItem
79 /** XAccessible implementation for a toolbox item which is represented by a VCL Window
81 class OToolBoxWindowItem
: public OAccessibleWrapper
84 sal_Int32 m_nIndexInParent
;
87 OToolBoxWindowItem(sal_Int32 _nIndexInParent
,
88 const css::uno::Reference
< css::uno::XComponentContext
>& _rxContext
,
89 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxInnerAccessible
,
90 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxParentAccessible
91 ) : OAccessibleWrapper(
95 ,m_nIndexInParent(_nIndexInParent
)
100 // OAccessibleWrapper
101 virtual rtl::Reference
<OAccessibleContextWrapper
> createAccessibleContext(
102 const css::uno::Reference
< css::accessibility::XAccessibleContext
>& _rxInnerContext
106 rtl::Reference
<OAccessibleContextWrapper
> OToolBoxWindowItem::createAccessibleContext(
107 const Reference
< XAccessibleContext
>& _rxInnerContext
)
109 return new OToolBoxWindowItemContext( m_nIndexInParent
, getComponentContext(), _rxInnerContext
, this, getParent() );
113 // VCLXAccessibleToolBox
115 VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow
* pVCLXWindow
) :
117 ImplInheritanceHelper( pVCLXWindow
)
122 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
126 VCLXAccessibleToolBoxItem
* VCLXAccessibleToolBox::GetItem_Impl( ToolBox::ImplToolItems::size_type _nPos
)
128 VCLXAccessibleToolBoxItem
* pItem
= nullptr;
129 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
132 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
133 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
134 // returns only toolbox buttons, not windows
135 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is())
136 pItem
= aIter
->second
.get();
142 void VCLXAccessibleToolBox::UpdateFocus_Impl()
144 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
148 // submit events only if toolbox has the focus to avoid sending events due to mouse move
149 bool bHasFocus
= false;
150 if ( pToolBox
->HasFocus() )
154 // check for subtoolbar, i.e. check if our parent is a toolbar
155 ToolBox
* pToolBoxParent
= dynamic_cast< ToolBox
* >( pToolBox
->GetParent() );
156 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
157 if ( pToolBoxParent
&& pToolBoxParent
->HasFocus() )
164 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
165 sal_uInt16 nFocusCount
= 0;
166 for ( const auto& [rPos
, rxChild
] : m_aAccessibleChildren
)
168 ToolBoxItemId nItemId
= pToolBox
->GetItemId( rPos
);
172 VCLXAccessibleToolBoxItem
* pItem
= rxChild
.get();
173 if ( pItem
->HasFocus() && nItemId
!= nHighlightItemId
)
175 // reset the old focused item
176 pItem
->SetFocus( false );
179 if ( nItemId
== nHighlightItemId
)
181 // set the new focused item
182 pItem
->SetFocus( true );
186 // both items changed?
187 if ( nFocusCount
> 1 )
192 void VCLXAccessibleToolBox::ReleaseFocus_Impl( ToolBox::ImplToolItems::size_type _nPos
)
194 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
195 if ( pToolBox
) // #107124#, do not check for focus because this message is also handled in losefocus
197 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
198 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
199 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
201 VCLXAccessibleToolBoxItem
* pItem
= aIter
->second
.get();
202 if ( pItem
->HasFocus() )
203 pItem
->SetFocus( false );
208 void VCLXAccessibleToolBox::UpdateChecked_Impl( ToolBox::ImplToolItems::size_type _nPos
)
210 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
214 ToolBoxItemId nFocusId
= pToolBox
->GetItemId( _nPos
);
215 VCLXAccessibleToolBoxItem
* pFocusItem
= nullptr;
217 for ( const auto& [rPos
, rxChild
] : m_aAccessibleChildren
)
219 ToolBoxItemId nItemId
= pToolBox
->GetItemId( rPos
);
221 VCLXAccessibleToolBoxItem
* pItem
= rxChild
.get();
222 pItem
->SetChecked( pToolBox
->IsItemChecked( nItemId
) );
223 if ( nItemId
== nFocusId
)
226 //Solution:If the position is not a child item,the focus should not be called
227 if ( pFocusItem
&& _nPos
!= ToolBox::ITEM_NOTFOUND
)
228 pFocusItem
->SetFocus( true );
231 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( ToolBox::ImplToolItems::size_type _nPos
)
233 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
237 ToolBoxItemId nItemId
= pToolBox
->GetItemId( _nPos
);
239 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
240 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
241 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
243 VCLXAccessibleToolBoxItem
* pItem
= aIter
->second
.get();
245 pItem
->SetIndeterminate( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
);
249 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator
const & _rMapPos
,
250 bool _bNotifyRemoval
)
252 rtl::Reference
<VCLXAccessibleToolBoxItem
> xItemAcc(_rMapPos
->second
);
253 if ( !xItemAcc
.is() )
256 if ( _bNotifyRemoval
)
258 NotifyAccessibleEvent(AccessibleEventId::CHILD
, Any(Reference
<XAccessible
>(xItemAcc
)), Any());
261 xItemAcc
->ReleaseToolBox();
265 void VCLXAccessibleToolBox::UpdateItem_Impl( ToolBox::ImplToolItems::size_type _nPos
)
267 if ( _nPos
< m_aAccessibleChildren
.size() )
269 UpdateAllItems_Impl();
273 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
277 // adjust the "index-in-parent"s
278 ToolBoxItemsMap::iterator aIndexAdjust
= m_aAccessibleChildren
.upper_bound( _nPos
);
279 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
280 while ( m_aAccessibleChildren
.end() != aIndexAdjust
)
282 rtl::Reference
<VCLXAccessibleToolBoxItem
> xItem(aIndexAdjust
->second
);
285 sal_Int32 nIndex
= xItem
->getIndexInParent();
287 xItem
->setIndexInParent(nIndex
);
293 // TODO: we should make this dependent on the existence of event listeners
294 // with the current implementation, we always create accessible object
295 Any
aNewChild( getAccessibleChild( static_cast<sal_Int64
>(_nPos
) ) );
296 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
297 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewChild
);
300 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
302 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
306 // deregister the old items
307 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
308 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
310 implReleaseToolboxItem( aIter
, true );
312 m_aAccessibleChildren
.clear();
314 // register the new items
315 ToolBox::ImplToolItems::size_type i
, nCount
= pToolBox
->GetItemCount();
316 for ( i
= 0; i
< nCount
; ++i
)
319 aNewValue
<<= getAccessibleChild(i
);
320 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
324 void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( vcl::Window
* pWindow
, bool bOpen
)
326 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
327 if( !(pWindow
&& pToolBox
) )
330 const ToolBoxItemId nDownItem
= pToolBox
->GetDownItemId();
332 // No item is currently in down state.
333 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
336 Reference
< XAccessible
> xChild( pWindow
->GetAccessible() );
339 Reference
< XAccessible
> xChildItem( getAccessibleChild(pToolBox
->GetItemPos(nDownItem
)));
340 VCLXAccessibleToolBoxItem
* pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( xChildItem
.get() );
342 pItem
->SetChild( xChild
);
343 pItem
->NotifyChildEvent( xChild
, bOpen
);
347 void VCLXAccessibleToolBox::UpdateItemName_Impl( ToolBox::ImplToolItems::size_type _nPos
)
349 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
);
351 pItem
->NameChanged();
354 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( ToolBox::ImplToolItems::size_type _nPos
)
356 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
);
358 pItem
->ToggleEnableState();
361 void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent
& rVclWindowEvent
)
363 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
364 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
367 && pToolBox
== pChildWindow
->GetParent()
368 && pChildWindow
->GetType() == WindowType::TOOLBOX
) )
371 const ToolBoxItemId
nCurItemId( pToolBox
->GetCurItemId() );
373 // No item is currently active (might happen when opening the overflow popup).
374 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
377 ToolBox::ImplToolItems::size_type nIndex
= pToolBox
->GetItemPos( nCurItemId
);
378 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
381 Reference
< XAccessible
> xChild
= pChildWindow
->GetAccessible();
382 VCLXAccessibleToolBoxItem
* pItem
=
383 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
384 pItem
->SetChild( xChild
);
385 pItem
->NotifyChildEvent( xChild
, true/*_bShow*/ );
389 void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox
* _pSubToolBox
)
391 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
395 ToolBox::ImplToolItems::size_type nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
396 if ( nIndex
== ToolBox::ITEM_NOTFOUND
)
399 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
403 Reference
< XAccessible
> xChild
= _pSubToolBox
->GetAccessible();
404 VCLXAccessibleToolBoxItem
* pItem
=
405 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
406 if ( pItem
->GetChild() == xChild
)
408 pItem
->SetChild( Reference
< XAccessible
>() );
409 pItem
->NotifyChildEvent( xChild
, false );
413 void VCLXAccessibleToolBox::FillAccessibleStateSet( sal_Int64
& rStateSet
)
415 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
417 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
420 rStateSet
|= AccessibleStateType::FOCUSABLE
;
421 if ( pToolBox
->IsHorizontal() )
422 rStateSet
|= AccessibleStateType::HORIZONTAL
;
424 rStateSet
|= AccessibleStateType::VERTICAL
;
428 void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
430 // to prevent an early release of the toolbox (VclEventId::ObjectDying)
431 Reference
< XAccessibleContext
> xHoldAlive
= this;
433 switch ( rVclWindowEvent
.GetId() )
435 case VclEventId::ToolboxClick
:
436 case VclEventId::ToolboxSelect
:
438 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
439 if ( rVclWindowEvent
.GetData() )
441 UpdateChecked_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
442 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
444 else if( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) != ToolBox::ITEM_NOTFOUND
)
446 UpdateChecked_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
447 UpdateIndeterminate_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
451 case VclEventId::ToolboxDoubleClick
:
452 case VclEventId::ToolboxActivate
:
453 case VclEventId::ToolboxDeactivate
:
454 //case VclEventId::ToolboxSelect:
457 case VclEventId::ToolboxItemUpdated
:
459 if ( rVclWindowEvent
.GetData() )
461 UpdateChecked_Impl( ToolBox::ITEM_NOTFOUND
);
462 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
467 case VclEventId::ToolboxHighlight
:
471 case VclEventId::ToolboxHighlightOff
:
472 ReleaseFocus_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
475 case VclEventId::ToolboxItemAdded
:
476 UpdateItem_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
479 case VclEventId::ToolboxItemRemoved
:
480 case VclEventId::ToolboxAllItemsChanged
:
482 UpdateAllItems_Impl();
486 case VclEventId::ToolboxItemWindowChanged
:
488 auto nPos
= static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
489 ToolBoxItemsMap::iterator
aAccessiblePos( m_aAccessibleChildren
.find( nPos
) );
490 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
491 if ( m_aAccessibleChildren
.end() != aAccessiblePos
)
493 implReleaseToolboxItem( aAccessiblePos
, false );
494 m_aAccessibleChildren
.erase (aAccessiblePos
);
498 aNewValue
<<= getAccessibleChild(nPos
);
499 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
502 case VclEventId::ToolboxItemTextChanged
:
503 UpdateItemName_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
506 case VclEventId::ToolboxItemEnabled
:
507 case VclEventId::ToolboxItemDisabled
:
509 UpdateItemEnabled_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
513 case VclEventId::DropdownOpen
:
514 case VclEventId::DropdownClose
:
516 UpdateCustomPopupItemp_Impl( static_cast< vcl::Window
* >( rVclWindowEvent
.GetData() ), rVclWindowEvent
.GetId() == VclEventId::DropdownOpen
);
520 case VclEventId::ObjectDying
:
522 // if this toolbox is a subtoolbox, we have to release it from its parent
523 VclPtr
< vcl::Window
> pWin
= GetAs
< vcl::Window
>();
524 if ( pWin
&& pWin
->GetParent() &&
525 pWin
->GetParent()->GetType() == WindowType::TOOLBOX
)
527 auto pParentAccContext
= pWin
->GetParent()->GetAccessible()->getAccessibleContext();
528 VCLXAccessibleToolBox
* pParent
= static_cast< VCLXAccessibleToolBox
* >( pParentAccContext
.get() );
530 pParent
->ReleaseSubToolBox(static_cast<ToolBox
*>(pWin
.get()));
534 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
535 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
537 implReleaseToolboxItem( aIter
, false );
539 m_aAccessibleChildren
.clear();
541 [[fallthrough
]]; // call base class
545 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
549 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
551 switch ( rVclWindowEvent
.GetId() )
553 case VclEventId::WindowShow
: // send create on show for direct accessible children
555 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
557 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), Any(xReturn
) );
559 HandleSubToolBarEvent( rVclWindowEvent
);
564 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
570 void SAL_CALL
VCLXAccessibleToolBox::disposing()
572 VCLXAccessibleComponent::disposing();
575 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
576 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
578 implReleaseToolboxItem( aIter
, false );
580 m_aAccessibleChildren
.clear();
584 OUString
VCLXAccessibleToolBox::getImplementationName()
586 return u
"com.sun.star.comp.toolkit.AccessibleToolBox"_ustr
;
589 Sequence
< OUString
> VCLXAccessibleToolBox::getSupportedServiceNames()
591 return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(),
592 Sequence
<OUString
>{u
"com.sun.star.accessibility.AccessibleToolBox"_ustr
});
595 // XAccessibleContext
596 sal_Int64 SAL_CALL
VCLXAccessibleToolBox::getAccessibleChildCount( )
598 comphelper::OExternalLockGuard
aGuard( this );
599 return implGetAccessibleChildCount();
602 sal_Int64
VCLXAccessibleToolBox::implGetAccessibleChildCount( )
604 sal_Int64 nCount
= 0;
605 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
607 nCount
= pToolBox
->GetItemCount();
612 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleChild( sal_Int64 i
)
614 comphelper::OExternalLockGuard
aGuard( this );
616 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
617 if ( (!pToolBox
) || i
< 0 || o3tl::make_unsigned(i
) >= pToolBox
->GetItemCount() )
618 throw IndexOutOfBoundsException();
620 rtl::Reference
< VCLXAccessibleToolBoxItem
> xChild
;
621 // search for the child
622 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find(i
);
623 if ( m_aAccessibleChildren
.end() == aIter
)
625 ToolBoxItemId nItemId
= pToolBox
->GetItemId( i
);
626 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
627 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
628 // not found -> create a new child
629 xChild
= new VCLXAccessibleToolBoxItem( pToolBox
, i
);
632 Reference
< XAccessible
> xParent
= xChild
;
633 auto const xInnerAcc(pItemWindow
->GetAccessible());
634 if (xInnerAcc
) // else child is being disposed - avoid crashing
636 rtl::Reference
<OToolBoxWindowItem
> xChild2(new OToolBoxWindowItem(0,
637 ::comphelper::getProcessComponentContext(), xInnerAcc
, xParent
));
638 pItemWindow
->SetAccessible(xChild2
);
639 xChild
->SetChild( xChild2
);
642 if ( nHighlightItemId
> ToolBoxItemId(0) && nItemId
== nHighlightItemId
)
643 xChild
->SetFocus( true );
644 if ( pToolBox
->IsItemChecked( nItemId
) )
645 xChild
->SetChecked( true );
646 if ( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
)
647 xChild
->SetIndeterminate( true );
648 m_aAccessibleChildren
.emplace( i
, xChild
);
653 xChild
= aIter
->second
;
658 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point
& _rPoint
)
660 comphelper::OExternalLockGuard
aGuard( this );
662 Reference
< XAccessible
> xAccessible
;
663 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
666 ToolBox::ImplToolItems::size_type nItemPos
667 = pToolBox
->GetItemPos(VCLUnoHelper::ConvertToVCLPoint(_rPoint
));
668 if ( nItemPos
!= ToolBox::ITEM_NOTFOUND
)
669 xAccessible
= getAccessibleChild( nItemPos
);
675 Reference
< XAccessible
> VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent
& rVclWindowEvent
)
677 Reference
< XAccessible
> xReturn
;
678 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
679 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
680 if ( pChildWindow
&& pToolBox
)
682 ToolBox::ImplToolItems::size_type nCount
= pToolBox
->GetItemCount();
683 for (ToolBox::ImplToolItems::size_type i
= 0 ; i
< nCount
&& !xReturn
.is() ; ++i
)
685 ToolBoxItemId nItemId
= pToolBox
->GetItemId( i
);
686 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
687 if ( pItemWindow
== pChildWindow
)
688 xReturn
= getAccessibleChild(i
);
694 Reference
< XAccessible
> VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
696 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
699 xReturn
= VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent
);
703 // XAccessibleSelection
704 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int64 nChildIndex
)
706 OExternalLockGuard
aGuard( this );
708 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
709 if ( (!pToolBox
) || nChildIndex
< 0 || o3tl::make_unsigned(nChildIndex
) >= pToolBox
->GetItemCount() )
710 throw IndexOutOfBoundsException();
712 pToolBox
->ChangeHighlight( nChildIndex
);
715 sal_Bool
VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int64 nChildIndex
)
717 OExternalLockGuard
aGuard( this );
718 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
719 if ( (!pToolBox
) || nChildIndex
< 0 || o3tl::make_unsigned(nChildIndex
) >= pToolBox
->GetItemCount() )
720 throw IndexOutOfBoundsException();
722 if ( pToolBox
->GetHighlightItemId() == pToolBox
->GetItemId( nChildIndex
) )
728 void VCLXAccessibleToolBox::clearAccessibleSelection( )
730 OExternalLockGuard
aGuard( this );
731 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
732 pToolBox
-> LoseFocus();
735 void VCLXAccessibleToolBox::selectAllAccessibleChildren( )
737 OExternalLockGuard
aGuard( this );
738 // intentionally empty. makes no sense for a toolbox
741 sal_Int64
VCLXAccessibleToolBox::getSelectedAccessibleChildCount( )
743 OExternalLockGuard
aGuard( this );
746 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
749 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
750 for ( size_t i
= 0, nCount
= pToolBox
->GetItemCount(); i
< nCount
; i
++ )
752 if ( nHighlightItemId
== pToolBox
->GetItemId( i
) )
755 break; // a toolbox can only have (n)one selected child
763 Reference
< XAccessible
> VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex
)
765 OExternalLockGuard
aGuard( this );
766 if ( nSelectedChildIndex
!= 0 )
767 throw IndexOutOfBoundsException();
769 Reference
< XAccessible
> xChild
;
770 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
773 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
774 for (ToolBox::ImplToolItems::size_type i
= 0, nCount
= pToolBox
->GetItemCount(); i
< nCount
; i
++ )
776 if ( nHighlightItemId
== pToolBox
->GetItemId( i
) )
778 xChild
= getAccessibleChild( i
);
785 throw IndexOutOfBoundsException();
790 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int64 nChildIndex
)
792 OExternalLockGuard
aGuard( this );
793 if ( nChildIndex
< 0 || nChildIndex
>= implGetAccessibleChildCount() )
794 throw IndexOutOfBoundsException();
795 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */