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>
24 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
25 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <o3tl/safeint.hxx>
28 #include <vcl/toolbox.hxx>
29 #include <vcl/unohelp.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(ToolBox
* pToolBox
)
116 : ImplInheritanceHelper(pToolBox
)
120 VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
124 VCLXAccessibleToolBoxItem
* VCLXAccessibleToolBox::GetItem_Impl( ToolBox::ImplToolItems::size_type _nPos
)
126 VCLXAccessibleToolBoxItem
* pItem
= nullptr;
127 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
130 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
131 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
132 // returns only toolbox buttons, not windows
133 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is())
134 pItem
= aIter
->second
.get();
140 void VCLXAccessibleToolBox::UpdateFocus_Impl()
142 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
146 // submit events only if toolbox has the focus to avoid sending events due to mouse move
147 bool bHasFocus
= false;
148 if ( pToolBox
->HasFocus() )
152 // check for subtoolbar, i.e. check if our parent is a toolbar
153 ToolBox
* pToolBoxParent
= dynamic_cast< ToolBox
* >( pToolBox
->GetParent() );
154 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
155 if ( pToolBoxParent
&& pToolBoxParent
->HasFocus() )
162 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
163 sal_uInt16 nFocusCount
= 0;
164 for ( const auto& [rPos
, rxChild
] : m_aAccessibleChildren
)
166 ToolBoxItemId nItemId
= pToolBox
->GetItemId( rPos
);
170 VCLXAccessibleToolBoxItem
* pItem
= rxChild
.get();
171 if ( pItem
->HasFocus() && nItemId
!= nHighlightItemId
)
173 // reset the old focused item
174 pItem
->SetFocus( false );
177 if ( nItemId
== nHighlightItemId
)
179 // set the new focused item
180 pItem
->SetFocus( true );
184 // both items changed?
185 if ( nFocusCount
> 1 )
190 void VCLXAccessibleToolBox::ReleaseFocus_Impl( ToolBox::ImplToolItems::size_type _nPos
)
192 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
193 if ( pToolBox
) // #107124#, do not check for focus because this message is also handled in losefocus
195 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
196 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
197 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
199 VCLXAccessibleToolBoxItem
* pItem
= aIter
->second
.get();
200 if ( pItem
->HasFocus() )
201 pItem
->SetFocus( false );
206 void VCLXAccessibleToolBox::UpdateChecked_Impl( ToolBox::ImplToolItems::size_type _nPos
)
208 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
212 ToolBoxItemId nFocusId
= pToolBox
->GetItemId( _nPos
);
213 VCLXAccessibleToolBoxItem
* pFocusItem
= nullptr;
215 for ( const auto& [rPos
, rxChild
] : m_aAccessibleChildren
)
217 ToolBoxItemId nItemId
= pToolBox
->GetItemId( rPos
);
219 VCLXAccessibleToolBoxItem
* pItem
= rxChild
.get();
220 pItem
->SetChecked( pToolBox
->IsItemChecked( nItemId
) );
221 if ( nItemId
== nFocusId
)
224 //Solution:If the position is not a child item,the focus should not be called
225 if ( pFocusItem
&& _nPos
!= ToolBox::ITEM_NOTFOUND
)
226 pFocusItem
->SetFocus( true );
229 void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( ToolBox::ImplToolItems::size_type _nPos
)
231 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
235 ToolBoxItemId nItemId
= pToolBox
->GetItemId( _nPos
);
237 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find( _nPos
);
238 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
239 if ( aIter
!= m_aAccessibleChildren
.end() && aIter
->second
.is() )
241 VCLXAccessibleToolBoxItem
* pItem
= aIter
->second
.get();
243 pItem
->SetIndeterminate( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
);
247 void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator
const & _rMapPos
,
248 bool _bNotifyRemoval
)
250 rtl::Reference
<VCLXAccessibleToolBoxItem
> xItemAcc(_rMapPos
->second
);
251 if ( !xItemAcc
.is() )
254 if ( _bNotifyRemoval
)
256 NotifyAccessibleEvent(AccessibleEventId::CHILD
, Any(Reference
<XAccessible
>(xItemAcc
)), Any());
259 xItemAcc
->ReleaseToolBox();
263 void VCLXAccessibleToolBox::UpdateItem_Impl( ToolBox::ImplToolItems::size_type _nPos
)
265 if ( _nPos
< m_aAccessibleChildren
.size() )
267 UpdateAllItems_Impl();
271 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
275 // adjust the "index-in-parent"s
276 ToolBoxItemsMap::iterator aIndexAdjust
= m_aAccessibleChildren
.upper_bound( _nPos
);
277 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
278 while ( m_aAccessibleChildren
.end() != aIndexAdjust
)
280 rtl::Reference
<VCLXAccessibleToolBoxItem
> xItem(aIndexAdjust
->second
);
283 sal_Int32 nIndex
= xItem
->getIndexInParent();
285 xItem
->setIndexInParent(nIndex
);
291 // TODO: we should make this dependent on the existence of event listeners
292 // with the current implementation, we always create accessible object
293 Any
aNewChild( getAccessibleChild( static_cast<sal_Int64
>(_nPos
) ) );
294 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
295 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewChild
);
298 void VCLXAccessibleToolBox::UpdateAllItems_Impl()
300 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
304 // deregister the old items
305 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
306 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
308 implReleaseToolboxItem( aIter
, true );
310 m_aAccessibleChildren
.clear();
312 // register the new items
313 ToolBox::ImplToolItems::size_type i
, nCount
= pToolBox
->GetItemCount();
314 for ( i
= 0; i
< nCount
; ++i
)
317 aNewValue
<<= getAccessibleChild(i
);
318 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
322 void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( vcl::Window
* pWindow
, bool bOpen
)
324 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
325 if( !(pWindow
&& pToolBox
) )
328 const ToolBoxItemId nDownItem
= pToolBox
->GetDownItemId();
330 // No item is currently in down state.
331 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
334 Reference
< XAccessible
> xChild( pWindow
->GetAccessible() );
337 Reference
< XAccessible
> xChildItem( getAccessibleChild(pToolBox
->GetItemPos(nDownItem
)));
338 VCLXAccessibleToolBoxItem
* pItem
= static_cast< VCLXAccessibleToolBoxItem
* >( xChildItem
.get() );
340 pItem
->SetChild( xChild
);
341 pItem
->NotifyChildEvent( xChild
, bOpen
);
345 void VCLXAccessibleToolBox::UpdateItemName_Impl( ToolBox::ImplToolItems::size_type _nPos
)
347 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
);
349 pItem
->NameChanged();
352 void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( ToolBox::ImplToolItems::size_type _nPos
)
354 VCLXAccessibleToolBoxItem
* pItem
= GetItem_Impl( _nPos
);
356 pItem
->ToggleEnableState();
359 void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent
& rVclWindowEvent
)
361 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
362 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
365 && pToolBox
== pChildWindow
->GetParent()
366 && pChildWindow
->GetType() == WindowType::TOOLBOX
) )
369 const ToolBoxItemId
nCurItemId( pToolBox
->GetCurItemId() );
371 // No item is currently active (might happen when opening the overflow popup).
372 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
375 ToolBox::ImplToolItems::size_type nIndex
= pToolBox
->GetItemPos( nCurItemId
);
376 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
379 Reference
< XAccessible
> xChild
= pChildWindow
->GetAccessible();
380 VCLXAccessibleToolBoxItem
* pItem
=
381 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
382 pItem
->SetChild( xChild
);
383 pItem
->NotifyChildEvent( xChild
, true/*_bShow*/ );
387 void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox
* _pSubToolBox
)
389 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
393 ToolBox::ImplToolItems::size_type nIndex
= pToolBox
->GetItemPos( pToolBox
->GetCurItemId() );
394 if ( nIndex
== ToolBox::ITEM_NOTFOUND
)
397 Reference
< XAccessible
> xItem
= getAccessibleChild( nIndex
);
401 Reference
< XAccessible
> xChild
= _pSubToolBox
->GetAccessible();
402 VCLXAccessibleToolBoxItem
* pItem
=
403 static_cast< VCLXAccessibleToolBoxItem
* >( xItem
.get() );
404 if ( pItem
->GetChild() == xChild
)
406 pItem
->SetChild( Reference
< XAccessible
>() );
407 pItem
->NotifyChildEvent( xChild
, false );
411 void VCLXAccessibleToolBox::FillAccessibleStateSet( sal_Int64
& rStateSet
)
413 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
415 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
418 rStateSet
|= AccessibleStateType::FOCUSABLE
;
419 if ( pToolBox
->IsHorizontal() )
420 rStateSet
|= AccessibleStateType::HORIZONTAL
;
422 rStateSet
|= AccessibleStateType::VERTICAL
;
426 void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
428 // to prevent an early release of the toolbox (VclEventId::ObjectDying)
429 Reference
< XAccessibleContext
> xHoldAlive
= this;
431 switch ( rVclWindowEvent
.GetId() )
433 case VclEventId::ToolboxClick
:
434 case VclEventId::ToolboxSelect
:
436 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
437 if ( rVclWindowEvent
.GetData() )
439 UpdateChecked_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
440 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
442 else if( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) != ToolBox::ITEM_NOTFOUND
)
444 UpdateChecked_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
445 UpdateIndeterminate_Impl( pToolBox
->GetItemPos(pToolBox
->GetCurItemId()) );
449 case VclEventId::ToolboxDoubleClick
:
450 case VclEventId::ToolboxActivate
:
451 case VclEventId::ToolboxDeactivate
:
452 //case VclEventId::ToolboxSelect:
455 case VclEventId::ToolboxItemUpdated
:
457 if ( rVclWindowEvent
.GetData() )
459 UpdateChecked_Impl( ToolBox::ITEM_NOTFOUND
);
460 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
465 case VclEventId::ToolboxHighlight
:
469 case VclEventId::ToolboxHighlightOff
:
470 ReleaseFocus_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
473 case VclEventId::ToolboxItemAdded
:
474 UpdateItem_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
477 case VclEventId::ToolboxItemRemoved
:
478 case VclEventId::ToolboxAllItemsChanged
:
480 UpdateAllItems_Impl();
484 case VclEventId::ToolboxItemWindowChanged
:
486 auto nPos
= static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
487 ToolBoxItemsMap::iterator
aAccessiblePos( m_aAccessibleChildren
.find( nPos
) );
488 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
489 if ( m_aAccessibleChildren
.end() != aAccessiblePos
)
491 implReleaseToolboxItem( aAccessiblePos
, false );
492 m_aAccessibleChildren
.erase (aAccessiblePos
);
496 aNewValue
<<= getAccessibleChild(nPos
);
497 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), aNewValue
);
500 case VclEventId::ToolboxItemTextChanged
:
501 UpdateItemName_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
504 case VclEventId::ToolboxItemEnabled
:
505 case VclEventId::ToolboxItemDisabled
:
507 UpdateItemEnabled_Impl( static_cast<ToolBox::ImplToolItems::size_type
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData())) );
511 case VclEventId::DropdownOpen
:
512 case VclEventId::DropdownClose
:
514 UpdateCustomPopupItemp_Impl( static_cast< vcl::Window
* >( rVclWindowEvent
.GetData() ), rVclWindowEvent
.GetId() == VclEventId::DropdownOpen
);
518 case VclEventId::ObjectDying
:
520 // if this toolbox is a subtoolbox, we have to release it from its parent
521 VclPtr
< vcl::Window
> pWin
= GetAs
< vcl::Window
>();
522 if ( pWin
&& pWin
->GetParent() &&
523 pWin
->GetParent()->GetType() == WindowType::TOOLBOX
)
525 auto pParentAccContext
= pWin
->GetParent()->GetAccessible()->getAccessibleContext();
526 VCLXAccessibleToolBox
* pParent
= static_cast< VCLXAccessibleToolBox
* >( pParentAccContext
.get() );
528 pParent
->ReleaseSubToolBox(static_cast<ToolBox
*>(pWin
.get()));
532 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
533 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
535 implReleaseToolboxItem( aIter
, false );
537 m_aAccessibleChildren
.clear();
539 [[fallthrough
]]; // call base class
543 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
547 void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
549 switch ( rVclWindowEvent
.GetId() )
551 case VclEventId::WindowShow
: // send create on show for direct accessible children
553 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
555 NotifyAccessibleEvent( AccessibleEventId::CHILD
, Any(), Any(xReturn
) );
557 HandleSubToolBarEvent( rVclWindowEvent
);
562 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
568 void SAL_CALL
VCLXAccessibleToolBox::disposing()
570 VCLXAccessibleComponent::disposing();
573 for ( ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.begin();
574 aIter
!= m_aAccessibleChildren
.end(); ++aIter
)
576 implReleaseToolboxItem( aIter
, false );
578 m_aAccessibleChildren
.clear();
582 OUString
VCLXAccessibleToolBox::getImplementationName()
584 return u
"com.sun.star.comp.toolkit.AccessibleToolBox"_ustr
;
587 Sequence
< OUString
> VCLXAccessibleToolBox::getSupportedServiceNames()
589 return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(),
590 std::initializer_list
<OUString
>{u
"com.sun.star.accessibility.AccessibleToolBox"_ustr
});
593 // XAccessibleContext
594 sal_Int64 SAL_CALL
VCLXAccessibleToolBox::getAccessibleChildCount( )
596 comphelper::OExternalLockGuard
aGuard( this );
597 return implGetAccessibleChildCount();
600 sal_Int64
VCLXAccessibleToolBox::implGetAccessibleChildCount( )
602 sal_Int64 nCount
= 0;
603 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
605 nCount
= pToolBox
->GetItemCount();
610 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleChild( sal_Int64 i
)
612 comphelper::OExternalLockGuard
aGuard( this );
614 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
615 if ( (!pToolBox
) || i
< 0 || o3tl::make_unsigned(i
) >= pToolBox
->GetItemCount() )
616 throw IndexOutOfBoundsException();
618 rtl::Reference
< VCLXAccessibleToolBoxItem
> xChild
;
619 // search for the child
620 ToolBoxItemsMap::iterator aIter
= m_aAccessibleChildren
.find(i
);
621 if ( m_aAccessibleChildren
.end() == aIter
)
623 ToolBoxItemId nItemId
= pToolBox
->GetItemId( i
);
624 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
625 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
626 // not found -> create a new child
627 xChild
= new VCLXAccessibleToolBoxItem( pToolBox
, i
);
630 Reference
< XAccessible
> xParent
= xChild
;
631 auto const xInnerAcc(pItemWindow
->GetAccessible());
632 if (xInnerAcc
) // else child is being disposed - avoid crashing
634 rtl::Reference
<OToolBoxWindowItem
> xChild2(new OToolBoxWindowItem(0,
635 ::comphelper::getProcessComponentContext(), xInnerAcc
, xParent
));
636 pItemWindow
->SetAccessible(xChild2
);
637 xChild
->SetChild( xChild2
);
640 if ( nHighlightItemId
> ToolBoxItemId(0) && nItemId
== nHighlightItemId
)
641 xChild
->SetFocus( true );
642 if ( pToolBox
->IsItemChecked( nItemId
) )
643 xChild
->SetChecked( true );
644 if ( pToolBox
->GetItemState( nItemId
) == TRISTATE_INDET
)
645 xChild
->SetIndeterminate( true );
646 m_aAccessibleChildren
.emplace( i
, xChild
);
651 xChild
= aIter
->second
;
656 Reference
< XAccessible
> SAL_CALL
VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point
& _rPoint
)
658 comphelper::OExternalLockGuard
aGuard( this );
660 Reference
< XAccessible
> xAccessible
;
661 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
664 ToolBox::ImplToolItems::size_type nItemPos
665 = pToolBox
->GetItemPos(vcl::unohelper::ConvertToVCLPoint(_rPoint
));
666 if ( nItemPos
!= ToolBox::ITEM_NOTFOUND
)
667 xAccessible
= getAccessibleChild( nItemPos
);
673 Reference
< XAccessible
> VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent
& rVclWindowEvent
)
675 Reference
< XAccessible
> xReturn
;
676 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
677 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
678 if ( pChildWindow
&& pToolBox
)
680 ToolBox::ImplToolItems::size_type nCount
= pToolBox
->GetItemCount();
681 for (ToolBox::ImplToolItems::size_type i
= 0 ; i
< nCount
&& !xReturn
.is() ; ++i
)
683 ToolBoxItemId nItemId
= pToolBox
->GetItemId( i
);
684 vcl::Window
* pItemWindow
= pToolBox
->GetItemWindow( nItemId
);
685 if ( pItemWindow
== pChildWindow
)
686 xReturn
= getAccessibleChild(i
);
692 Reference
< XAccessible
> VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
694 Reference
< XAccessible
> xReturn
= GetItemWindowAccessible(rVclWindowEvent
);
697 xReturn
= VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent
);
701 // XAccessibleSelection
702 void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int64 nChildIndex
)
704 OExternalLockGuard
aGuard( this );
706 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
707 if ( (!pToolBox
) || nChildIndex
< 0 || o3tl::make_unsigned(nChildIndex
) >= pToolBox
->GetItemCount() )
708 throw IndexOutOfBoundsException();
710 pToolBox
->ChangeHighlight( nChildIndex
);
713 sal_Bool
VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int64 nChildIndex
)
715 OExternalLockGuard
aGuard( this );
716 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
717 if ( (!pToolBox
) || nChildIndex
< 0 || o3tl::make_unsigned(nChildIndex
) >= pToolBox
->GetItemCount() )
718 throw IndexOutOfBoundsException();
720 if ( pToolBox
->GetHighlightItemId() == pToolBox
->GetItemId( nChildIndex
) )
726 void VCLXAccessibleToolBox::clearAccessibleSelection( )
728 OExternalLockGuard
aGuard( this );
729 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
730 pToolBox
-> LoseFocus();
733 void VCLXAccessibleToolBox::selectAllAccessibleChildren( )
735 OExternalLockGuard
aGuard( this );
736 // intentionally empty. makes no sense for a toolbox
739 sal_Int64
VCLXAccessibleToolBox::getSelectedAccessibleChildCount( )
741 OExternalLockGuard
aGuard( this );
744 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
747 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
748 for ( size_t i
= 0, nCount
= pToolBox
->GetItemCount(); i
< nCount
; i
++ )
750 if ( nHighlightItemId
== pToolBox
->GetItemId( i
) )
753 break; // a toolbox can only have (n)one selected child
761 Reference
< XAccessible
> VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex
)
763 OExternalLockGuard
aGuard( this );
764 if ( nSelectedChildIndex
!= 0 )
765 throw IndexOutOfBoundsException();
767 Reference
< XAccessible
> xChild
;
768 VclPtr
< ToolBox
> pToolBox
= GetAs
< ToolBox
>();
771 ToolBoxItemId nHighlightItemId
= pToolBox
->GetHighlightItemId();
772 for (ToolBox::ImplToolItems::size_type i
= 0, nCount
= pToolBox
->GetItemCount(); i
< nCount
; i
++ )
774 if ( nHighlightItemId
== pToolBox
->GetItemId( i
) )
776 xChild
= getAccessibleChild( i
);
783 throw IndexOutOfBoundsException();
788 void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int64 nChildIndex
)
790 OExternalLockGuard
aGuard( this );
791 if ( nChildIndex
< 0 || nChildIndex
>= implGetAccessibleChildCount() )
792 throw IndexOutOfBoundsException();
793 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */