LibreOffice Module accessibility (master) 1
vclxaccessiblelist.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
23
25#include <com/sun/star/accessibility/AccessibleStateType.hpp>
26#include <com/sun/star/accessibility/AccessibleEventId.hpp>
27#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
28#include <com/sun/star/accessibility/AccessibleRole.hpp>
29#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30#include <o3tl/safeint.hxx>
31#include <vcl/svapp.hxx>
35
36using namespace ::com::sun::star;
37using namespace ::com::sun::star::uno;
38using namespace ::com::sun::star::lang;
39using namespace ::com::sun::star::beans;
40using namespace ::com::sun::star::accessibility;
41using namespace ::accessibility;
42
43namespace
44{
46 void checkSelection_Impl( sal_Int64 _nIndex, const IComboListBoxHelper& _rListBox, bool bSelected )
47 {
48 sal_Int32 nCount = bSelected ? _rListBox.GetSelectedEntryCount()
49 : _rListBox.GetEntryCount();
50 if ( _nIndex < 0 || _nIndex >= nCount )
51 throw css::lang::IndexOutOfBoundsException();
52 }
53}
54
56 const Reference< XAccessible >& _xParent)
57 : ImplInheritanceHelper (pVCLWindow),
58 m_aBoxType (aBoxType),
59 m_nVisibleLineCount (0),
60 m_nIndexInParent (DEFAULT_INDEX_IN_PARENT),
61 m_nLastTopEntry ( 0 ),
62 m_nLastSelectedPos ( LISTBOX_ENTRY_NOTFOUND ),
63 m_bDisableProcessEvent ( false ),
64 m_bVisible ( true ),
65 m_nCurSelectedPos ( LISTBOX_ENTRY_NOTFOUND ),
66 m_xParent ( _xParent )
67{
68 // Because combo boxes and list boxes don't have a common interface for
69 // methods with identical signature we have to write down twice the
70 // same code.
71 switch (m_aBoxType)
72 {
73 case COMBOBOX:
74 {
75 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
76 if ( pBox )
78 break;
79 }
80
81 case LISTBOX:
82 {
83 VclPtr< ListBox > pBox = GetAs< ListBox >();
84 if ( pBox )
86 break;
87 }
88 }
91 {
92 m_nCurSelectedPos=m_pListBoxHelper->GetSelectedEntryPos(0);
93 }
94 sal_uInt16 nCount = static_cast<sal_uInt16>(getAccessibleChildCount());
96}
97
98
100{
102}
103
104
106{
107 VCLXAccessibleComponent::disposing();
108
109 // Dispose all items in the list.
110 m_aAccessibleChildren.clear();
111
112 m_pListBoxHelper.reset();
113}
114
115
117{
118 SolarMutexGuard aSolarGuard;
119
120 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
121 // check if our list should be visible
123 && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN
124 && !m_pListBoxHelper->IsInDropDown() )
125 {
126 rStateSet &= ~AccessibleStateType::VISIBLE;
127 rStateSet &= ~AccessibleStateType::SHOWING;
128 m_bVisible = false;
129 }
130
131 // Both the combo box and list box are handled identical in the
132 // following but for some reason they don't have a common interface for
133 // the methods used.
134 if ( m_pListBoxHelper )
135 {
136 if ( m_pListBoxHelper->IsMultiSelectionEnabled() )
137 rStateSet |= AccessibleStateType::MULTI_SELECTABLE;
138 rStateSet |= AccessibleStateType::FOCUSABLE;
139 // All children are transient.
140 rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS;
141 }
142}
143
145{
146 m_bVisible = _bSetNew;
147 Any aOldValue, aNewValue;
148 (_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::VISIBLE;
149 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
150 (_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::SHOWING;
151 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
152
153 ListItems::iterator aIter = m_aAccessibleChildren.begin();
155 // adjust the index inside the VCLXAccessibleListItem
156 for ( ; aIter != m_aAccessibleChildren.end(); )
157 {
158 Reference< XAccessible > xHold = *aIter;
159 if (!xHold.is())
160 {
161 aIter = m_aAccessibleChildren.erase(aIter);
162 }
163 else
164 {
165 VCLXAccessibleListItem* pItem = static_cast<VCLXAccessibleListItem*>(xHold.get());
166 const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0;
167 const sal_Int32 nPos = static_cast<sal_Int32>(aIter - m_aAccessibleChildren.begin());
168 bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
169 pItem->SetVisible( m_bVisible && bVisible );
170 ++aIter;
171 }
172
173 }
174}
175
176void VCLXAccessibleList::UpdateSelection_Acc (std::u16string_view /*sTextOfSelectedItem*/, bool b_IsDropDownList)
177{
178 if ( m_aBoxType != COMBOBOX )
179 return;
180
181 /* FIXME: is there something missing here? nIndex is unused. Looks like
182 * copy-paste from VCLXAccessibleList::UpdateSelection() */
183 // VclPtr< ComboBox > pBox = GetAs< ComboBox >();
184 // if ( pBox )
185 // {
186 // // Find the index of the selected item inside the VCL control...
187 // sal_Int32 nIndex = pBox->GetEntryPos(sTextOfSelectedItem);
188 // // ...and then find the associated accessibility object.
189 // if ( nIndex == LISTBOX_ENTRY_NOTFOUND )
190 // nIndex = 0;
191 UpdateSelection_Impl_Acc(b_IsDropDownList);
192 // }
193}
194
195
197{
198 uno::Any aOldValue, aNewValue;
199
200 {
201 SolarMutexGuard aSolarGuard;
202 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
204 if ( m_pListBoxHelper )
205 {
206 sal_Int32 i=0;
208 for ( const auto& rChild : m_aAccessibleChildren )
209 {
210 Reference< XAccessible > xHold = rChild;
211 if ( xHold.is() )
212 {
213 VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
214 // Retrieve the item's index from the list entry.
215 bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
216 if (bNowSelected)
218
219 if ( bNowSelected && !pItem->IsSelected() )
220 {
221 xNewAcc = rChild;
222 aNewValue <<= xNewAcc;
223 }
224 else if ( pItem->IsSelected() )
226
227 pItem->SetSelected( bNowSelected );
228 }
229 else
230 { // it could happen that a child was not created before
231 checkEntrySelected(i,aNewValue,xNewAcc);
232 }
233 ++i;
234 }
235 const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount();
236 if ( i < nCount ) // here we have to check the if any other listbox entry is selected
237 {
238 for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
239 ;
240 }
241 if ( xNewAcc.is() && GetWindow()->HasFocus() )
242 {
244 aOldValue <<= getAccessibleChild( m_nLastSelectedPos );
245 aNewValue <<= xNewAcc;
246 }
247 }
248 }
249
250 if (m_aBoxType == COMBOBOX)
251 {
252 //VCLXAccessibleDropDownComboBox
253 //when in list is dropped down, xText = NULL
254 if (bHasDropDownList && m_pListBoxHelper && m_pListBoxHelper->IsInDropDown())
255 {
256 if ( aNewValue.hasValue() || aOldValue.hasValue() )
257 {
258 NotifyAccessibleEvent(
259 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
260 aOldValue,
261 aNewValue );
262
263 NotifyListItem(aNewValue);
264 }
265 }
266 else
267 {
268 //VCLXAccessibleComboBox
269 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, uno::Any(), uno::Any() );
270 }
271 }
272 else if (m_aBoxType == LISTBOX)
273 {
274 if ( aNewValue.hasValue() || aOldValue.hasValue() )
275 {
276 NotifyAccessibleEvent(
277 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
278 aOldValue,
279 aNewValue );
280
281 NotifyListItem(aNewValue);
282 }
283 }
284}
285
286void VCLXAccessibleList::NotifyListItem(css::uno::Any const & val)
287{
289 val >>= xCurItem;
290 if (xCurItem.is())
291 {
292 VCLXAccessibleListItem* pCurItem = static_cast< VCLXAccessibleListItem* >(xCurItem.get());
293 if (pCurItem)
294 {
295 pCurItem->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED,Any(),Any());
296 }
297 }
298}
299
300void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent, bool b_IsDropDownList)
301{
302 switch ( rVclWindowEvent.GetId() )
303 {
304 case VclEventId::DropdownSelect:
305 case VclEventId::ListboxSelect:
307 UpdateSelection_Impl_Acc(b_IsDropDownList);
308 break;
309 case VclEventId::WindowGetFocus:
310 break;
311 case VclEventId::ControlGetFocus:
312 {
313 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
314 if (m_aBoxType == COMBOBOX && b_IsDropDownList)
315 {
316 //VCLXAccessibleDropDownComboBox
317 }
318 else if (m_aBoxType == LISTBOX && b_IsDropDownList)
319 {
320 }
321 else if ( m_aBoxType == LISTBOX && !b_IsDropDownList)
322 {
323 if ( m_pListBoxHelper )
324 {
325 uno::Any aOldValue,
326 aNewValue;
327 sal_Int32 nPos = m_nCurSelectedPos; //m_pListBoxHelper->GetSelectedEntryPos();
328
330 nPos = m_pListBoxHelper->GetTopEntry();
332 aNewValue <<= CreateChild(nPos);
333 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
334 aOldValue,
335 aNewValue );
336 }
337 }
338 }
339 break;
340 default:
341 break;
342 }
343
344}
345
347{
348 // Create a reference to this object to prevent an early release of the
349 // listbox (VclEventId::ObjectDying).
350 Reference< XAccessible > xHoldAlive = this;
351
352 switch ( rVclWindowEvent.GetId() )
353 {
354 case VclEventId::DropdownOpen:
356 break;
357 case VclEventId::DropdownClose:
358 notifyVisibleStates(false);
359 break;
360 case VclEventId::ListboxScrolled:
362 break;
363
364 // The selection events VclEventId::ComboboxSelect and
365 // VclEventId::ComboboxDeselect are not handled here because here we
366 // have no access to the edit field. Its text is necessary to
367 // identify the currently selected item.
368
369 case VclEventId::ObjectDying:
370 {
371 dispose();
372
373 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
374 break;
375 }
376
377 case VclEventId::ListboxItemRemoved:
378 case VclEventId::ComboboxItemRemoved:
379 case VclEventId::ListboxItemAdded:
380 case VclEventId::ComboboxItemAdded:
382 break;
383 case VclEventId::ControlGetFocus:
384 {
385 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
386 // Added by IBM Symphony Acc team to handle the list item focus when List control get focus
387 bool b_IsDropDownList = true;
389 b_IsDropDownList = ((m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN);
390 if ( m_aBoxType == LISTBOX && !b_IsDropDownList )
391 {
392 if ( m_pListBoxHelper )
393 {
394 uno::Any aOldValue,
395 aNewValue;
396 sal_Int32 nPos = m_nCurSelectedPos;
397
399 nPos = m_pListBoxHelper->GetTopEntry();
401 aNewValue <<= CreateChild(nPos);
402 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
403 aOldValue,
404 aNewValue );
405 }
406 }
407 }
408 break;
409
410 default:
411 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
412 }
413}
414
416{
417 VclPtr< ListBox > pBox = GetAs< ListBox >();
418 if( m_aBoxType == LISTBOX )
419 {
420 if (m_pListBoxHelper && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) != WB_DROPDOWN)
421 {
422 uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pBox->GetAccessible() };
423 rRelationSet.AddRelation( com::sun::star::accessibility::AccessibleRelation( com::sun::star::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
424 }
425 }
426 else
427 {
428 VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
429 }
430}
431
432
437void VCLXAccessibleList::UpdateSelection (std::u16string_view sTextOfSelectedItem)
438{
439 if ( m_aBoxType != COMBOBOX )
440 return;
441
442 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
443 if ( pBox )
444 {
445 // Find the index of the selected item inside the VCL control...
446 sal_Int32 nIndex = pBox->GetEntryPos(sTextOfSelectedItem);
447 // ...and then find the associated accessibility object.
449 nIndex = 0;
451 }
452}
453
454
455Reference<XAccessible> VCLXAccessibleList::CreateChild (sal_Int32 nPos)
456{
457 Reference<XAccessible> xChild;
458
460 {
461 m_aAccessibleChildren.resize(nPos + 1);
462
463 // insert into the container
464 xChild = new VCLXAccessibleListItem(nPos, this);
465 m_aAccessibleChildren[nPos] = xChild;
466 }
467 else
468 {
469 xChild = m_aAccessibleChildren[nPos];
470 // check if position is empty and can be used else we have to adjust all entries behind this
471 if (!xChild.is())
472 {
473 xChild = new VCLXAccessibleListItem(nPos, this);
474 m_aAccessibleChildren[nPos] = xChild;
475 }
476 }
477
478 if ( xChild.is() )
479 {
480 // Just add the SELECTED state.
481 bool bNowSelected = false;
482 if ( m_pListBoxHelper )
483 bNowSelected = m_pListBoxHelper->IsEntryPosSelected(nPos);
484 if (bNowSelected)
486 VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(xChild.get());
487 pItem->SetSelected( bNowSelected );
488
489 // Set the child's VISIBLE state.
491 const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0;
492 bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
493 pItem->SetVisible( m_bVisible && bVisible );
494 }
495
496 return xChild;
497}
498
499
501{
502 m_aAccessibleChildren.clear();
503 NotifyAccessibleEvent (
504 AccessibleEventId::INVALIDATE_ALL_CHILDREN,
505 Any(), Any());
506}
507
508// XAccessible
509
510Reference<XAccessibleContext> SAL_CALL
512{
513 return this;
514}
515
516
517// XAccessibleContext
518
520{
521 SolarMutexGuard aSolarGuard;
522 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
524}
525
527{
528 sal_Int32 nCount = 0;
529 if ( m_pListBoxHelper )
530 nCount = m_pListBoxHelper->GetEntryCount();
531
532 return nCount;
533}
534
535Reference<XAccessible> SAL_CALL VCLXAccessibleList::getAccessibleChild (sal_Int64 i)
536{
537 SolarMutexGuard aSolarGuard;
538 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
539
540 if ( i < 0 || i >= getAccessibleChildCount() )
541 throw IndexOutOfBoundsException();
542
544 // search for the child
546 xChild = CreateChild (i);
547 else
548 {
549 xChild = m_aAccessibleChildren[i];
550 if ( !xChild.is() )
551 xChild = CreateChild (i);
552 }
553 OSL_ENSURE( xChild.is(), "VCLXAccessibleList::getAccessibleChild: returning empty child!" );
554 return xChild;
555}
556
558{
559 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
560
561 return m_xParent;
562}
563
565{
567 return m_nIndexInParent;
568 else
569 return VCLXAccessibleComponent::getAccessibleIndexInParent();
570}
571
573{
574 return AccessibleRole::LIST;
575}
576
577// XServiceInfo
579{
580 return "com.sun.star.comp.toolkit.AccessibleList";
581}
582
584{
585 return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(),
586 Sequence<OUString>{"com.sun.star.accessibility.AccessibleList"});
587}
588
590{
591 if ( m_pListBoxHelper )
592 {
593 if ( (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
594 m_nVisibleLineCount = m_pListBoxHelper->GetDisplayLineCount();
595 else
596 {
597 sal_uInt16 nCols = 0,
598 nLines = 0;
599 m_pListBoxHelper->GetMaxVisColumnsAndLines (nCols, nLines);
600 m_nVisibleLineCount = nLines;
601 }
602 }
603}
604
606{
607 SolarMutexGuard aSolarGuard;
608 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
609
610 sal_Int32 nTop = m_nLastTopEntry;
611
612 if ( m_pListBoxHelper )
613 nTop = m_pListBoxHelper->GetTopEntry();
614 if ( nTop != m_nLastTopEntry )
615 {
617 sal_Int32 nBegin = std::min( m_nLastTopEntry, nTop );
618 sal_Int32 nEnd = std::max( m_nLastTopEntry + m_nVisibleLineCount, nTop + m_nVisibleLineCount );
619 for (sal_Int32 i = nBegin; (i <= nEnd); ++i)
620 {
621 bool bVisible = ( i >= nTop && i < ( nTop + m_nVisibleLineCount ) );
624 xHold = m_aAccessibleChildren[i];
625 else if ( bVisible )
626 xHold = CreateChild(i);
627
628 if ( xHold.is() )
629 static_cast< VCLXAccessibleListItem* >( xHold.get() )->SetVisible( m_bVisible && bVisible );
630 }
631 }
632
633 m_nLastTopEntry = nTop;
634}
635
636bool VCLXAccessibleList::checkEntrySelected(sal_Int32 _nPos,Any& _rNewValue,Reference< XAccessible >& _rxNewAcc)
637{
638 OSL_ENSURE(m_pListBoxHelper,"Helper is not valid!");
639 bool bNowSelected = false;
640 if ( m_pListBoxHelper )
641 {
642 bNowSelected = m_pListBoxHelper->IsEntryPosSelected (_nPos);
643 if ( bNowSelected )
644 {
645 _rxNewAcc = CreateChild(_nPos);
646 _rNewValue <<= _rxNewAcc;
647 }
648 }
649 return bNowSelected;
650}
651
652
654{
655 uno::Any aOldValue, aNewValue;
656
657 {
658 SolarMutexGuard aSolarGuard;
659 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
661
662 if ( m_pListBoxHelper )
663 {
664 sal_Int32 i=0;
666 for ( const auto& rChild : m_aAccessibleChildren )
667 {
668 Reference< XAccessible > xHold = rChild;
669 if ( xHold.is() )
670 {
671 VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
672 // Retrieve the item's index from the list entry.
673 bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
674 if (bNowSelected)
676
677 if ( bNowSelected && !pItem->IsSelected() )
678 {
679 xNewAcc = rChild;
680 aNewValue <<= xNewAcc;
681 }
682 else if ( pItem->IsSelected() )
684
685 pItem->SetSelected( bNowSelected );
686 }
687 else
688 { // it could happen that a child was not created before
689 checkEntrySelected(i,aNewValue,xNewAcc);
690 }
691 ++i;
692 }
693 const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount();
694 if ( i < nCount ) // here we have to check the if any other listbox entry is selected
695 {
696 for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
697 ;
698 }
699 if ( xNewAcc.is() && GetWindow()->HasFocus() )
700 {
702 aOldValue <<= getAccessibleChild( m_nLastSelectedPos );
703 aNewValue <<= xNewAcc;
704 }
705 if (m_pListBoxHelper->IsInDropDown())
706 {
707 if ( aNewValue.hasValue() || aOldValue.hasValue() )
708 NotifyAccessibleEvent(
709 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
710 aOldValue,
711 aNewValue );
712 //the SELECTION_CHANGED is not necessary
713 //NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
714 }
715 }
716 }
717}
718
719
720// XAccessibleSelection
721
722void SAL_CALL VCLXAccessibleList::selectAccessibleChild( sal_Int64 nChildIndex )
723{
724 bool bNotify = false;
725
726 {
727 SolarMutexGuard aSolarGuard;
728 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
729
730 if ( m_pListBoxHelper )
731 {
732 checkSelection_Impl(nChildIndex,*m_pListBoxHelper,false);
733
734 m_pListBoxHelper->SelectEntryPos( static_cast<sal_uInt16>(nChildIndex) );
735 // call the select handler, don't handle events in this time
737 m_pListBoxHelper->Select();
739 bNotify = true;
740 }
741 }
742
743 if ( bNotify )
745}
746
748{
749 SolarMutexGuard aSolarGuard;
750 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
751
752 bool bRet = false;
753 if ( m_pListBoxHelper )
754 {
755 checkSelection_Impl(nChildIndex,*m_pListBoxHelper,false);
756
757 bRet = m_pListBoxHelper->IsEntryPosSelected( static_cast<sal_uInt16>(nChildIndex) );
758 }
759 return bRet;
760}
761
763{
764 bool bNotify = false;
765
766 {
767 SolarMutexGuard aSolarGuard;
768 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
769
770 if ( m_pListBoxHelper )
771 {
772 m_pListBoxHelper->SetNoSelection();
773 bNotify = true;
774 }
775 }
776
777 if ( bNotify )
779}
780
782{
783 bool bNotify = false;
784
785 {
786 SolarMutexGuard aSolarGuard;
787 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
788
789 if ( m_pListBoxHelper )
790 {
791 const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount();
792 for ( sal_Int32 i = 0; i < nCount; ++i )
793 m_pListBoxHelper->SelectEntryPos( i );
794 // call the select handler, don't handle events in this time
796 m_pListBoxHelper->Select();
798 bNotify = true;
799 }
800 }
801
802 if ( bNotify )
804}
805
807{
808 SolarMutexGuard aSolarGuard;
809 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
810
811 sal_Int64 nCount = 0;
812 if ( m_pListBoxHelper )
813 nCount = m_pListBoxHelper->GetSelectedEntryCount();
814 return nCount;
815}
816
818{
819 SolarMutexGuard aSolarGuard;
820 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
821
822 if ( m_pListBoxHelper )
823 {
824 checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,true);
825 return getAccessibleChild( m_pListBoxHelper->GetSelectedEntryPos( static_cast<sal_uInt16>(nSelectedChildIndex) ) );
826 }
827
828 return nullptr;
829}
830
831void SAL_CALL VCLXAccessibleList::deselectAccessibleChild( sal_Int64 nSelectedChildIndex )
832{
833 bool bNotify = false;
834
835 {
836 SolarMutexGuard aSolarGuard;
837 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
838
839 if ( m_pListBoxHelper )
840 {
841 checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,false);
842
843 m_pListBoxHelper->SelectEntryPos( static_cast<sal_uInt16>(nSelectedChildIndex), false );
844 // call the select handler, don't handle events in this time
846 m_pListBoxHelper->Select();
848 bNotify = true;
849 }
850 }
851
852 if ( bNotify )
854}
855
857{
858 awt::Rectangle aBounds ( 0, 0, 0, 0 );
860 && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
861 {
862 if ( m_pListBoxHelper->IsInDropDown() )
863 aBounds = AWTRectangle(m_pListBoxHelper->GetDropDownPosSizePixel());
864 }
865 else
866 {
867 // a list has the same bounds as his parent but starts at (0,0)
868 aBounds = VCLXAccessibleComponent::implGetBounds();
869 aBounds.X = 0;
870 aBounds.Y = 0;
871 if ( m_aBoxType == COMBOBOX )
872 {
873 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
874 if ( pBox )
875 {
876 Size aSize = pBox->GetSubEdit()->GetSizePixel();
877 aBounds.Y += aSize.Height();
878 aBounds.Height -= aSize.Height();
879 }
880 }
881 }
882 return aBounds;
883}
884
885
887{
888 SolarMutexGuard aSolarGuard;
889 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
890
891 awt::Point aPos;
893 && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
894 {
895 if ( m_pListBoxHelper->IsInDropDown() )
896 aPos = AWTPoint(m_pListBoxHelper->GetDropDownPosSizePixel().TopLeft());
897 }
898 else
899 {
900 aPos = VCLXAccessibleComponent::getLocationOnScreen();
901 if ( m_aBoxType == COMBOBOX )
902 {
903 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
904 if ( pBox )
905 {
906 aPos.Y += pBox->GetSubEdit()->GetSizePixel().Height();
907 }
908 }
909 }
910 return aPos;
911}
912
913
915{
916 return m_pListBoxHelper->IsInDropDown();
917}
918
919
921{
926 {
928 if(xChild.is())
929 {
930 uno::Any aNewValue;
931 aNewValue <<= xChild;
932 NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, uno::Any(), aNewValue );
933 }
934 }
935}
936
937/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr tools::Long Height() const
the class OAccessibleListBoxEntry represents the base class for an accessible object of a listbox ent...
void NotifyAccessibleEvent(sal_Int16 _nEventId, const css::uno::Any &_aOldValue, const css::uno::Any &_aNewValue)
void SetVisible(bool _bVisible)
void SetSelected(bool _bSelected)
virtual void FillAccessibleStateSet(sal_Int64 &rStateSet) override
This method adds the states AccessibleStateType::FOCUSABLE and possibly AccessibleStateType::MULTI_SE...
virtual void SAL_CALL selectAccessibleChild(sal_Int64 nChildIndex) override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int64 nSelectedChildIndex) override
virtual sal_Int16 SAL_CALL getAccessibleRole() override
static void NotifyListItem(css::uno::Any const &val)
void notifyVisibleStates(bool _bSetNew)
virtual void FillAccessibleRelationSet(utl::AccessibleRelationSetHelper &rRelationSet) override
void UpdateSelection(std::u16string_view sTextOfSelectedItem)
Called on reception of selection events this method checks all known list items for a possible change...
css::uno::Reference< css::accessibility::XAccessible > m_xParent
We need to save the accessible parent to return it in getAccessibleParent(), because this method of t...
virtual void SAL_CALL deselectAccessibleChild(sal_Int64 nSelectedChildIndex) override
virtual void SAL_CALL disposing() override
This function is called from the implementation helper during a XComponent::dispose call.
sal_Int32 m_nIndexInParent
Index in parent. This is settable from the outside.
void UpdateSelection_Impl_Acc(bool b_IsDropDownList)
void HandleChangedItemList()
Call this method when the item list has been changed, i.e.
void UpdateSelection_Impl(sal_Int32 nPos=0)
virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount() override
bool checkEntrySelected(sal_Int32 _nPos, css::uno::Any &_rNewValue, css::uno::Reference< css::accessibility::XAccessible > &_rxNewAcc)
virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int64 nChildIndex) override
virtual css::awt::Rectangle implGetBounds() override
void SetIndexInParent(sal_Int32 nIndex)
The index that is passed to this method is returned on following calls to getAccessibleIndexInParent.
virtual sal_Int64 SAL_CALL getAccessibleChildCount() override final
virtual void SAL_CALL selectAllAccessibleChildren() override
std::unique_ptr<::accessibility::IComboListBoxHelper > m_pListBoxHelper
css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int64 i) override
virtual OUString SAL_CALL getImplementationName() override
css::uno::Reference< css::accessibility::XAccessible > CreateChild(sal_Int32 i)
Create the specified child and insert it into the list of children.
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
The index returned as index in parent is always the one set with the SetIndexInParent() method.
void UpdateSelection_Acc(std::u16string_view sTextOfSelectedItem, bool b_IsDropDownList)
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
virtual void SAL_CALL clearAccessibleSelection() override
VCLXAccessibleList(VCLXWindow *pVCLXindow, BoxType aBoxType, const css::uno::Reference< css::accessibility::XAccessible > &_xParent)
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual css::awt::Point SAL_CALL getLocationOnScreen() override
sal_Int64 implGetAccessibleChildCount()
virtual void ProcessWindowEvent(const VclWindowEvent &rVclWindowEvent) override
Process some of the events and delegate the rest to the base classes.
VclEventId GetId() const
void AddRelation(const css::accessibility::AccessibleRelation &rRelation)
css::awt::Point AWTPoint(const ::Point &rVCLPoint)
css::awt::Rectangle AWTRectangle(const ::tools::Rectangle &rVCLRect)
int nCount
sal_Int32 nIndex
sal_uInt16 nPos
const sal_Int32 DEFAULT_INDEX_IN_PARENT
#define LISTBOX_ENTRY_NOTFOUND
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
void dispose()
bool hasValue()
bool bVisible
unsigned char sal_Bool
WinBits const WB_DROPDOWN
sal_Int32 _nPos