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