xref: /AOO41X/main/accessibility/source/extended/accessiblelistbox.cxx (revision ffad8df045fe8db79e3e50f731c1fa6ab6501c83)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26 #include <accessibility/extended/accessiblelistbox.hxx>
27 #include <accessibility/extended/accessiblelistboxentry.hxx>
28 #include <svtools/svtreebx.hxx>
29 #include <com/sun/star/awt/Point.hpp>
30 #include <com/sun/star/awt/Rectangle.hpp>
31 #include <com/sun/star/awt/Size.hpp>
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 #include <com/sun/star/accessibility/AccessibleRole.hpp>
34 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35 #include <tools/debug.hxx>
36 #include <vcl/svapp.hxx>
37 #include <toolkit/awt/vclxwindow.hxx>
38 #include <toolkit/helper/convert.hxx>
39 #include <unotools/accessiblestatesethelper.hxx>
40 
41 //........................................................................
42 namespace accessibility
43 {
44 //........................................................................
45 
46     // class AccessibleListBox -----------------------------------------------------
47 
48     using namespace ::com::sun::star::accessibility;
49     using namespace ::com::sun::star::uno;
50     using namespace ::com::sun::star::lang;
51     using namespace ::com::sun::star;
52 
DBG_NAME(AccessibleListBox)53     DBG_NAME(AccessibleListBox)
54 
55     // -----------------------------------------------------------------------------
56     // Ctor() and Dtor()
57     // -----------------------------------------------------------------------------
58     AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) :
59 
60         VCLXAccessibleComponent( _rListBox.GetWindowPeer() ),
61         m_xParent( _xParent )
62     {
63         DBG_CTOR( AccessibleListBox, NULL );
64     }
65     // -----------------------------------------------------------------------------
~AccessibleListBox()66     AccessibleListBox::~AccessibleListBox()
67     {
68         DBG_DTOR( AccessibleListBox, NULL );
69         if ( isAlive() )
70         {
71             // increment ref count to prevent double call of Dtor
72             osl_incrementInterlockedCount( &m_refCount );
73             dispose();
74         }
75     }
IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox,VCLXAccessibleComponent,AccessibleListBox_BASE)76     IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
77     IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
78     // -----------------------------------------------------------------------------
79     SvTreeListBox* AccessibleListBox::getListBox() const
80     {
81         return  static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() );
82     }
83     // -----------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)84     void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
85     {
86         if ( isAlive() )
87         {
88             switch ( rVclWindowEvent.GetId() )
89             {
90                 case  VCLEVENT_CHECKBOX_TOGGLE :
91                 {
92                     if ( !getListBox() || !getListBox()->HasFocus() )
93                     {
94                         return;
95                     }
96                     AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent);
97                     if(!pCurOpEntry)
98                     {
99                         return ;
100                     }
101                     uno::Any aValue;
102                     aValue <<= AccessibleStateType::CHECKED;
103 
104                     if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED )
105                     {
106                         pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue );
107                     }
108                     else
109                     {
110                         pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() );
111                     }
112                     break;
113                 }
114 
115                 case VCLEVENT_LISTBOX_SELECT :
116                 {
117                     // First send an event that tells the listeners of a
118                     // modified selection.  The active descendant event is
119                     // send after that so that the receiving AT has time to
120                     // read the text or name of the active child.
121 //                    NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
122                     OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT");
123                 }
124                 case VCLEVENT_LISTBOX_TREESELECT:
125                     {
126                         if ( getListBox() && getListBox()->HasFocus() )
127                         {
128                             AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
129                             if (pEntry)
130                             {
131                                 pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
132                             }
133                         }
134                     }
135                     break;
136                 case VCLEVENT_LISTBOX_TREEFOCUS:
137                     {
138                         SvTreeListBox* pBox = getListBox();
139                         sal_Bool bNeedFocus = sal_False;
140                         if (pBox)
141                         {
142                             Window* pParent = ((Window*)pBox)->GetParent();
143                             if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW)
144                             {
145                                 // MT: ImplGetAppSVData shouldn't be exported from VCL.
146                                 // In which scenario is this needed?
147                                 // If needed, we need to find an other solution
148                                 /*
149                                 ImplSVData* pSVData = ImplGetAppSVData();
150                                 if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent)
151                                     bNeedFocus = sal_True;
152                                 */
153                             }
154                         }
155                         if( pBox && (pBox->HasFocus() || bNeedFocus) )
156                         {
157                             uno::Any aOldValue, aNewValue;
158                             SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
159                             if ( pEntry )
160                             {
161                                 AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
162                                 if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry)
163                                 {
164                                     aOldValue <<= uno::Any();
165                                     aNewValue <<= m_xFocusedChild;
166                                     NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
167                                     return ;
168                                 }
169 
170                                 aOldValue <<= m_xFocusedChild;
171 
172                                 MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
173                                 if(mi != m_mapEntry.end())
174                                 {
175                                     OSL_ASSERT(mi->second.get() != NULL);
176                                     m_xFocusedChild = mi->second;
177                                 }
178                                 else
179                                 {
180                                     AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
181                                     m_xFocusedChild = pEntNew;
182                                     m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew));
183                                 }
184 
185                                 aNewValue <<= m_xFocusedChild;
186                                 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
187                             }
188                             else
189                             {
190                                 aOldValue <<= uno::Any();
191                                 aNewValue <<= AccessibleStateType::FOCUSED;
192                                 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
193                             }
194                         }
195                     }
196                     break;
197                 case VCLEVENT_LISTBOX_ITEMREMOVED:
198                     {
199                         SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
200                         if ( pEntry )
201                         {
202                             RemoveChildEntries(pEntry);
203                         }
204                         else
205                         {
206                             // NULL means Clear()
207                             MAP_ENTRY::iterator mi = m_mapEntry.begin();
208                             for ( ; mi != m_mapEntry.end() ; ++mi)
209                             {
210                                 uno::Any aNewValue;
211                                 uno::Any aOldValue;
212                                 aOldValue <<= mi->second;
213                                 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
214                             }
215                             m_mapEntry.clear();
216                         }
217 
218 
219                     }
220                     break;
221 
222                 // --> OD 2009-04-01 #i92103#
223                 case VCLEVENT_ITEM_EXPANDED :
224                 case VCLEVENT_ITEM_COLLAPSED :
225                 {
226                     SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
227                     if ( pEntry )
228                     {
229                         AccessibleListBoxEntry* pAccListBoxEntry =
230                             new AccessibleListBoxEntry( *getListBox(), pEntry, this );
231                         Reference< XAccessible > xChild = pAccListBoxEntry;
232                         const short nAccEvent =
233                                 ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED )
234                                 ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
235                                 : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED;
236                         uno::Any aListBoxEntry;
237                         aListBoxEntry <<= xChild;
238                         NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry );
239                         if ( getListBox() && getListBox()->HasFocus() )
240                         {
241                             NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry );
242                         }
243                     }
244                 }
245                 break;
246                 // <--
247                 default:
248                     VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
249             }
250         }
251     }
252 
GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)253     AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent )
254     {
255         SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
256         if ( !pEntry )
257             pEntry = getListBox()->GetCurEntry();
258 
259         AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
260         if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry())
261         {
262             AccessibleListBoxEntry *pAccCurOptionEntry =NULL;
263             MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
264             if (mi != m_mapEntry.end())
265             {
266                 pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get());
267             }
268             else
269             {
270                 pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
271                 std::pair<MAP_ENTRY::iterator, bool> pairMi =  m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry));
272                 mi = pairMi.first;
273             }
274 
275             uno::Any aNewValue;
276             aNewValue <<= mi->second;//xAcc
277             NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add
278 
279             return pAccCurOptionEntry;
280         }
281         else
282         {
283             return pEntryFocus;
284         }
285         return NULL;
286     }
287 
RemoveChildEntries(SvLBoxEntry * pEntry)288     void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry)
289     {
290         MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
291         if ( mi != m_mapEntry.end() )
292         {
293             uno::Any aNewValue;
294             uno::Any aOldValue;
295             aOldValue <<= mi->second;
296             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
297 
298             m_mapEntry.erase(mi);
299         }
300 
301         SvTreeListBox* pBox = getListBox();
302         SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry);
303         while (pEntryChild)
304         {
305             RemoveChildEntries(pEntryChild);
306             pEntryChild = pBox->NextSibling(pEntryChild);
307         }
308     }
309 
310     // -----------------------------------------------------------------------------
ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)311     void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
312     {
313         switch ( rVclWindowEvent.GetId() )
314         {
315             case VCLEVENT_WINDOW_SHOW:
316             case VCLEVENT_WINDOW_HIDE:
317             {
318             }
319             break;
320             default:
321             {
322                 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
323             }
324             break;
325         }
326     }
327 
328     // -----------------------------------------------------------------------------
329     // XComponent
330     // -----------------------------------------------------------------------------
disposing()331     void SAL_CALL AccessibleListBox::disposing()
332     {
333         ::osl::MutexGuard aGuard( m_aMutex );
334 
335         m_mapEntry.clear();
336         VCLXAccessibleComponent::disposing();
337         m_xParent = NULL;
338     }
339     // -----------------------------------------------------------------------------
340     // XServiceInfo
341     // -----------------------------------------------------------------------------
getImplementationName()342     ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException)
343     {
344         return getImplementationName_Static();
345     }
346     // -----------------------------------------------------------------------------
getSupportedServiceNames()347     Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException)
348     {
349         return getSupportedServiceNames_Static();
350     }
351     // -----------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)352     sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
353     {
354         Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
355         const ::rtl::OUString* pSupported = aSupported.getConstArray();
356         const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
357         for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported )
358             ;
359 
360         return pSupported != pEnd;
361     }
362     // -----------------------------------------------------------------------------
363     // XServiceInfo - static methods
364     // -----------------------------------------------------------------------------
getSupportedServiceNames_Static(void)365     Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException )
366     {
367         Sequence< ::rtl::OUString > aSupported(3);
368         aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
369         aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
370         aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") );
371         return aSupported;
372     }
373     // -----------------------------------------------------------------------------
getImplementationName_Static(void)374     ::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException )
375     {
376         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") );
377     }
378     // -----------------------------------------------------------------------------
379     // XAccessible
380     // -----------------------------------------------------------------------------
getAccessibleContext()381     Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext(  ) throw (RuntimeException)
382     {
383         ensureAlive();
384         return this;
385     }
386     // -----------------------------------------------------------------------------
387     // XAccessibleContext
388     // -----------------------------------------------------------------------------
getAccessibleChildCount()389     sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount(  ) throw (RuntimeException)
390     {
391         ::comphelper::OExternalLockGuard aGuard( this );
392 
393         ensureAlive();
394 
395         sal_Int32 nCount = 0;
396         SvTreeListBox* pSvTreeListBox = getListBox();
397         if ( pSvTreeListBox )
398             nCount = pSvTreeListBox->GetLevelChildCount( NULL );
399 
400         return nCount;
401     }
402     // -----------------------------------------------------------------------------
getAccessibleChild(sal_Int32 i)403     Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
404     {
405         ::comphelper::OExternalLockGuard aGuard( this );
406 
407         ensureAlive();
408         SvLBoxEntry* pEntry = getListBox()->GetEntry(i);
409         if ( !pEntry )
410             throw IndexOutOfBoundsException();
411 
412         // Solution: Set the parameter of the parent to null to let entry determine the parent by itself
413         //return new AccessibleListBoxEntry( *getListBox(), pEntry, this );
414         return new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
415     }
416     // -----------------------------------------------------------------------------
getAccessibleParent()417     Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent(  ) throw (RuntimeException)
418     {
419         ::osl::MutexGuard aGuard( m_aMutex );
420 
421         ensureAlive();
422         return m_xParent;
423     }
424     // -----------------------------------------------------------------------------
getRoleType()425     sal_Int32 SAL_CALL AccessibleListBox::getRoleType()
426     {
427         sal_Int32 nCase = 0;
428         SvLBoxEntry* pEntry = getListBox()->GetEntry(0);
429         if ( pEntry )
430         {
431             if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0  )
432             {
433                 nCase = 1;
434                 return nCase;
435             }
436         }
437 
438         sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
439         if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) )
440         {
441             if( bHasButtons )
442                 nCase = 1;
443         }
444         else
445         {
446             if( bHasButtons )
447                 nCase = 2;
448              else
449                 nCase = 3;
450         }
451         return nCase;
452     }
getAccessibleRole()453     sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole(  ) throw (RuntimeException)
454     {
455         if(getListBox())
456         {
457             short nType = getListBox()->GetAllEntriesAccessibleRoleType();
458             if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE)
459                     return AccessibleRole::TREE;
460             else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST)
461                     return AccessibleRole::LIST;
462         }
463 
464         //o is: return AccessibleRole::TREE;
465         sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
466         if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN))
467             return AccessibleRole::LIST;
468         else
469             if(getRoleType() == 0)
470                 return AccessibleRole::LIST;
471             else
472             return AccessibleRole::TREE;
473     }
474     // -----------------------------------------------------------------------------
getAccessibleDescription()475     ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription(  ) throw (RuntimeException)
476     {
477         ::comphelper::OExternalLockGuard aGuard( this );
478 
479         ensureAlive();
480         return getListBox()->GetAccessibleDescription();
481     }
482     // -----------------------------------------------------------------------------
getAccessibleName()483     ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName(  ) throw (RuntimeException)
484     {
485         ::comphelper::OExternalLockGuard aGuard( this );
486 
487         ensureAlive();
488         return getListBox()->GetAccessibleName();
489     }
490     // -----------------------------------------------------------------------------
491     // XAccessibleSelection
492     // -----------------------------------------------------------------------------
selectAccessibleChild(sal_Int32 nChildIndex)493     void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
494     {
495         ::comphelper::OExternalLockGuard aGuard( this );
496 
497         ensureAlive();
498 
499         SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
500         if ( !pEntry )
501             throw IndexOutOfBoundsException();
502 
503         getListBox()->Select( pEntry, sal_True );
504     }
505     // -----------------------------------------------------------------------------
isAccessibleChildSelected(sal_Int32 nChildIndex)506     sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
507     {
508         ::comphelper::OExternalLockGuard aGuard( this );
509 
510         ensureAlive();
511 
512         SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
513         if ( !pEntry )
514             throw IndexOutOfBoundsException();
515 
516         return getListBox()->IsSelected( pEntry );
517     }
518     // -----------------------------------------------------------------------------
clearAccessibleSelection()519     void SAL_CALL AccessibleListBox::clearAccessibleSelection(  ) throw (RuntimeException)
520     {
521         ::comphelper::OExternalLockGuard aGuard( this );
522 
523         ensureAlive();
524 
525         sal_Int32 i, nCount = 0;
526         nCount = getListBox()->GetLevelChildCount( NULL );
527         for ( i = 0; i < nCount; ++i )
528         {
529             SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
530             if ( getListBox()->IsSelected( pEntry ) )
531                 getListBox()->Select( pEntry, sal_False );
532         }
533     }
534     // -----------------------------------------------------------------------------
selectAllAccessibleChildren()535     void SAL_CALL AccessibleListBox::selectAllAccessibleChildren(  ) throw (RuntimeException)
536     {
537         ::comphelper::OExternalLockGuard aGuard( this );
538 
539         ensureAlive();
540 
541         sal_Int32 i, nCount = 0;
542         nCount = getListBox()->GetLevelChildCount( NULL );
543         for ( i = 0; i < nCount; ++i )
544         {
545             SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
546             if ( !getListBox()->IsSelected( pEntry ) )
547                 getListBox()->Select( pEntry, sal_True );
548         }
549     }
550     // -----------------------------------------------------------------------------
getSelectedAccessibleChildCount()551     sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
552     {
553         ::comphelper::OExternalLockGuard aGuard( this );
554 
555         ensureAlive();
556 
557 
558 //      sal_Int32 i, nSelCount = 0, nCount = 0;
559 //      nCount = getListBox()->GetLevelChildCount( NULL );
560 //      for ( i = 0; i < nCount; ++i )
561 //      {
562 //          SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
563 //          if ( getListBox()->IsSelected( pEntry ) )
564 //              ++nSelCount;
565 //      }
566 //      return nSelCount;
567 
568         int nTestCount =  getListBox()->GetSelectionCount();
569         return nTestCount;
570     }
571     // -----------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572     Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
573     {
574         ::comphelper::OExternalLockGuard aGuard( this );
575 
576         ensureAlive();
577 
578         if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
579             throw IndexOutOfBoundsException();
580 
581         Reference< XAccessible > xChild;
582         sal_Int32 i, nSelCount = 0, nCount = 0;
583         nCount = getListBox()->GetLevelChildCount( NULL );
584         for ( i = 0; i < nCount; ++i )
585         {
586             SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
587             if ( getListBox()->IsSelected( pEntry ) )
588                 ++nSelCount;
589 
590             if ( nSelCount == ( nSelectedChildIndex + 1 ) )
591             {
592                 // Solution: Set the parameter of the parent to null to let entry determine the parent by itself
593                 //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
594                 xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
595                 break;
596             }
597         }
598 
599         return xChild;
600     }
601     // -----------------------------------------------------------------------------
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)602     void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
603     {
604         ::comphelper::OExternalLockGuard aGuard( this );
605 
606         ensureAlive();
607 
608         SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex );
609         if ( !pEntry )
610             throw IndexOutOfBoundsException();
611 
612         getListBox()->Select( pEntry, sal_False );
613     }
614     // -----------------------------------------------------------------------------
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)615     void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
616     {
617         VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
618         if ( getListBox() && isAlive() )
619         {
620             rStateSet.AddState( AccessibleStateType::FOCUSABLE );
621             rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
622             if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION )
623                 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
624         }
625     }
626 
627 
628 //........................................................................
629 }// namespace accessibility
630 //........................................................................
631 
632