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 .
20 #include <accessibility/extended/accessiblelistbox.hxx>
21 #include <accessibility/extended/accessiblelistboxentry.hxx>
22 #include <svtools/treelistbox.hxx>
23 #include <com/sun/star/awt/Point.hpp>
24 #include <com/sun/star/awt/Rectangle.hpp>
25 #include <com/sun/star/awt/Size.hpp>
26 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
27 #include <com/sun/star/accessibility/AccessibleRole.hpp>
28 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <vcl/svapp.hxx>
31 #include <toolkit/awt/vclxwindow.hxx>
32 #include <toolkit/helper/convert.hxx>
33 #include <unotools/accessiblestatesethelper.hxx>
35 //........................................................................
36 namespace accessibility
38 //........................................................................
40 // class AccessibleListBox -----------------------------------------------------
42 using namespace ::com::sun::star::accessibility
;
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::lang
;
45 using namespace ::com::sun::star
;
47 // -----------------------------------------------------------------------------
49 // -----------------------------------------------------------------------------
50 AccessibleListBox::AccessibleListBox( SvTreeListBox
& _rListBox
, const Reference
< XAccessible
>& _xParent
) :
52 VCLXAccessibleComponent( _rListBox
.GetWindowPeer() ),
56 // -----------------------------------------------------------------------------
57 AccessibleListBox::~AccessibleListBox()
61 // increment ref count to prevent double call of Dtor
62 osl_atomic_increment( &m_refCount
);
66 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox
, VCLXAccessibleComponent
, AccessibleListBox_BASE
)
67 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox
, VCLXAccessibleComponent
, AccessibleListBox_BASE
)
68 // -----------------------------------------------------------------------------
69 SvTreeListBox
* AccessibleListBox::getListBox() const
71 return static_cast< SvTreeListBox
* >( const_cast<AccessibleListBox
*>(this)->GetWindow() );
73 // -----------------------------------------------------------------------------
74 void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
78 switch ( rVclWindowEvent
.GetId() )
80 case VCLEVENT_CHECKBOX_TOGGLE
:
82 if ( getListBox() && getListBox()->HasFocus() )
84 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
86 pEntry
= getListBox()->GetCurEntry();
90 Reference
< XAccessible
> xChild
= new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
91 uno::Any aOldValue
, aNewValue
;
93 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aOldValue
, aNewValue
);
99 case VCLEVENT_LISTBOX_SELECT
:
101 // First send an event that tells the listeners of a
102 // modified selection. The active descendant event is
103 // send after that so that the receiving AT has time to
104 // read the text or name of the active child.
105 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
106 if ( getListBox() && getListBox()->HasFocus() )
108 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
111 Reference
< XAccessible
> xChild
= new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
112 uno::Any aOldValue
, aNewValue
;
113 aNewValue
<<= xChild
;
114 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aOldValue
, aNewValue
);
120 case VCLEVENT_ITEM_EXPANDED
:
121 case VCLEVENT_ITEM_COLLAPSED
:
123 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
126 AccessibleListBoxEntry
* pAccListBoxEntry
=
127 new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
128 Reference
< XAccessible
> xChild
= pAccListBoxEntry
;
129 const short nAccEvent
=
130 ( rVclWindowEvent
.GetId() == VCLEVENT_ITEM_EXPANDED
)
131 ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
132 : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED
;
133 uno::Any aListBoxEntry
;
134 aListBoxEntry
<<= xChild
;
135 NotifyAccessibleEvent( nAccEvent
, Any(), aListBoxEntry
);
136 if ( getListBox() && getListBox()->HasFocus() )
138 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, Any(), aListBoxEntry
);
145 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent
);
149 // -----------------------------------------------------------------------------
150 void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
152 switch ( rVclWindowEvent
.GetId() )
154 case VCLEVENT_WINDOW_SHOW
:
155 case VCLEVENT_WINDOW_HIDE
:
161 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
167 // -----------------------------------------------------------------------------
169 // -----------------------------------------------------------------------------
170 void SAL_CALL
AccessibleListBox::disposing()
172 ::osl::MutexGuard
aGuard( m_aMutex
);
174 VCLXAccessibleComponent::disposing();
177 // -----------------------------------------------------------------------------
179 // -----------------------------------------------------------------------------
180 OUString SAL_CALL
AccessibleListBox::getImplementationName() throw(RuntimeException
)
182 return getImplementationName_Static();
184 // -----------------------------------------------------------------------------
185 Sequence
< OUString
> SAL_CALL
AccessibleListBox::getSupportedServiceNames() throw(RuntimeException
)
187 return getSupportedServiceNames_Static();
189 // -----------------------------------------------------------------------------
190 sal_Bool SAL_CALL
AccessibleListBox::supportsService( const OUString
& _rServiceName
) throw (RuntimeException
)
192 return cppu::supportsService(this, _rServiceName
);
194 // -----------------------------------------------------------------------------
195 // XServiceInfo - static methods
196 // -----------------------------------------------------------------------------
197 Sequence
< OUString
> AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException
)
199 Sequence
< OUString
> aSupported(3);
200 aSupported
[0] = "com.sun.star.accessibility.AccessibleContext";
201 aSupported
[1] = "com.sun.star.accessibility.AccessibleComponent";
202 aSupported
[2] = "com.sun.star.awt.AccessibleTreeListBox";
205 // -----------------------------------------------------------------------------
206 OUString
AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException
)
208 return OUString( "com.sun.star.comp.svtools.AccessibleTreeListBox" );
210 // -----------------------------------------------------------------------------
212 // -----------------------------------------------------------------------------
213 Reference
< XAccessibleContext
> SAL_CALL
AccessibleListBox::getAccessibleContext( ) throw (RuntimeException
)
218 // -----------------------------------------------------------------------------
219 // XAccessibleContext
220 // -----------------------------------------------------------------------------
221 sal_Int32 SAL_CALL
AccessibleListBox::getAccessibleChildCount( ) throw (RuntimeException
)
223 ::comphelper::OExternalLockGuard
aGuard( this );
227 sal_Int32 nCount
= 0;
228 SvTreeListBox
* pSvTreeListBox
= getListBox();
229 if ( pSvTreeListBox
)
230 nCount
= pSvTreeListBox
->GetLevelChildCount( NULL
);
234 // -----------------------------------------------------------------------------
235 Reference
< XAccessible
> SAL_CALL
AccessibleListBox::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
,RuntimeException
)
237 ::comphelper::OExternalLockGuard
aGuard( this );
240 SvTreeListEntry
* pEntry
= getListBox()->GetEntry(i
);
242 throw IndexOutOfBoundsException();
244 return new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
246 // -----------------------------------------------------------------------------
247 Reference
< XAccessible
> SAL_CALL
AccessibleListBox::getAccessibleParent( ) throw (RuntimeException
)
249 ::osl::MutexGuard
aGuard( m_aMutex
);
254 // -----------------------------------------------------------------------------
255 sal_Int16 SAL_CALL
AccessibleListBox::getAccessibleRole( ) throw (RuntimeException
)
257 return AccessibleRole::TREE
;
259 // -----------------------------------------------------------------------------
260 OUString SAL_CALL
AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException
)
262 ::comphelper::OExternalLockGuard
aGuard( this );
265 return getListBox()->GetAccessibleDescription();
267 // -----------------------------------------------------------------------------
268 OUString SAL_CALL
AccessibleListBox::getAccessibleName( ) throw (RuntimeException
)
270 ::comphelper::OExternalLockGuard
aGuard( this );
273 return getListBox()->GetAccessibleName();
275 // -----------------------------------------------------------------------------
276 // XAccessibleSelection
277 // -----------------------------------------------------------------------------
278 void SAL_CALL
AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
280 ::comphelper::OExternalLockGuard
aGuard( this );
284 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( nChildIndex
);
286 throw IndexOutOfBoundsException();
288 getListBox()->Select( pEntry
, sal_True
);
290 // -----------------------------------------------------------------------------
291 sal_Bool SAL_CALL
AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
293 ::comphelper::OExternalLockGuard
aGuard( this );
297 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( nChildIndex
);
299 throw IndexOutOfBoundsException();
301 return getListBox()->IsSelected( pEntry
);
303 // -----------------------------------------------------------------------------
304 void SAL_CALL
AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException
)
306 ::comphelper::OExternalLockGuard
aGuard( this );
310 sal_Int32 nCount
= getListBox()->GetLevelChildCount( NULL
);
311 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
313 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( i
);
314 if ( getListBox()->IsSelected( pEntry
) )
315 getListBox()->Select( pEntry
, sal_False
);
318 // -----------------------------------------------------------------------------
319 void SAL_CALL
AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException
)
321 ::comphelper::OExternalLockGuard
aGuard( this );
325 sal_Int32 nCount
= getListBox()->GetLevelChildCount( NULL
);
326 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
328 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( i
);
329 if ( !getListBox()->IsSelected( pEntry
) )
330 getListBox()->Select( pEntry
, sal_True
);
333 // -----------------------------------------------------------------------------
334 sal_Int32 SAL_CALL
AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException
)
336 ::comphelper::OExternalLockGuard
aGuard( this );
340 sal_Int32 nSelCount
= 0;
341 sal_Int32 nCount
= getListBox()->GetLevelChildCount( NULL
);
342 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
344 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( i
);
345 if ( getListBox()->IsSelected( pEntry
) )
351 // -----------------------------------------------------------------------------
352 Reference
< XAccessible
> SAL_CALL
AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
354 ::comphelper::OExternalLockGuard
aGuard( this );
358 if ( nSelectedChildIndex
< 0 || nSelectedChildIndex
>= getSelectedAccessibleChildCount() )
359 throw IndexOutOfBoundsException();
361 Reference
< XAccessible
> xChild
;
362 sal_Int32 nSelCount
= 0;
363 sal_Int32 nCount
= getListBox()->GetLevelChildCount( NULL
);
364 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
366 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( i
);
367 if ( getListBox()->IsSelected( pEntry
) )
370 if ( nSelCount
== ( nSelectedChildIndex
+ 1 ) )
372 xChild
= new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
379 // -----------------------------------------------------------------------------
380 void SAL_CALL
AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
382 ::comphelper::OExternalLockGuard
aGuard( this );
386 SvTreeListEntry
* pEntry
= getListBox()->GetEntry( nSelectedChildIndex
);
388 throw IndexOutOfBoundsException();
390 getListBox()->Select( pEntry
, sal_False
);
392 // -----------------------------------------------------------------------------
393 void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
395 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
396 if ( getListBox() && isAlive() )
398 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
399 rStateSet
.AddState( AccessibleStateType::MANAGES_DESCENDANTS
);
400 if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION
)
401 rStateSet
.AddState( AccessibleStateType::MULTI_SELECTABLE
);
406 //........................................................................
407 }// namespace accessibility
408 //........................................................................
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */