1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accessiblelistbox.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_accessibility.hxx"
33 #include <accessibility/extended/accessiblelistbox.hxx>
34 #include <accessibility/extended/accessiblelistboxentry.hxx>
35 #include <svtools/svtreebx.hxx>
36 #include <com/sun/star/awt/Point.hpp>
37 #include <com/sun/star/awt/Rectangle.hpp>
38 #include <com/sun/star/awt/Size.hpp>
39 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
40 #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 #include <tools/debug.hxx>
43 #include <vcl/svapp.hxx>
44 #include <toolkit/awt/vclxwindow.hxx>
45 #include <toolkit/helper/convert.hxx>
46 #include <unotools/accessiblestatesethelper.hxx>
48 //........................................................................
49 namespace accessibility
51 //........................................................................
53 // class AccessibleListBox -----------------------------------------------------
55 using namespace ::com::sun::star::accessibility
;
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::lang
;
58 using namespace ::com::sun::star
;
60 DBG_NAME(AccessibleListBox
)
62 // -----------------------------------------------------------------------------
64 // -----------------------------------------------------------------------------
65 AccessibleListBox::AccessibleListBox( SvTreeListBox
& _rListBox
, const Reference
< XAccessible
>& _xParent
) :
67 VCLXAccessibleComponent( _rListBox
.GetWindowPeer() ),
70 DBG_CTOR( AccessibleListBox
, NULL
);
72 // -----------------------------------------------------------------------------
73 AccessibleListBox::~AccessibleListBox()
75 DBG_DTOR( AccessibleListBox
, NULL
);
78 // increment ref count to prevent double call of Dtor
79 osl_incrementInterlockedCount( &m_refCount
);
83 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox
, VCLXAccessibleComponent
, AccessibleListBox_BASE
)
84 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox
, VCLXAccessibleComponent
, AccessibleListBox_BASE
)
85 // -----------------------------------------------------------------------------
86 SvTreeListBox
* AccessibleListBox::getListBox() const
88 return static_cast< SvTreeListBox
* >( const_cast<AccessibleListBox
*>(this)->GetWindow() );
90 // -----------------------------------------------------------------------------
91 void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
95 switch ( rVclWindowEvent
.GetId() )
97 case VCLEVENT_CHECKBOX_TOGGLE
:
99 if ( getListBox() && getListBox()->HasFocus() )
101 SvLBoxEntry
* pEntry
= static_cast< SvLBoxEntry
* >( rVclWindowEvent
.GetData() );
103 pEntry
= getListBox()->GetCurEntry();
107 Reference
< XAccessible
> xChild
= new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
108 uno::Any aOldValue
, aNewValue
;
109 aNewValue
<<= xChild
;
110 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aOldValue
, aNewValue
);
116 case VCLEVENT_LISTBOX_SELECT
:
118 // First send an event that tells the listeners of a
119 // modified selection. The active descendant event is
120 // send after that so that the receiving AT has time to
121 // read the text or name of the active child.
122 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
123 if ( getListBox() && getListBox()->HasFocus() )
125 SvLBoxEntry
* pEntry
= static_cast< SvLBoxEntry
* >( rVclWindowEvent
.GetData() );
128 Reference
< XAccessible
> xChild
= new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
129 uno::Any aOldValue
, aNewValue
;
130 aNewValue
<<= xChild
;
131 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aOldValue
, aNewValue
);
136 // --> OD 2009-04-01 #i92103#
137 case VCLEVENT_LISTBOX_ENTRY_EXPANDED
:
138 case VCLEVENT_LISTBOX_ENTRY_COLLAPSED
:
140 SvLBoxEntry
* pEntry
= static_cast< SvLBoxEntry
* >( rVclWindowEvent
.GetData() );
143 AccessibleListBoxEntry
* pAccListBoxEntry
=
144 new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
145 Reference
< XAccessible
> xChild
= pAccListBoxEntry
;
146 const short nAccEvent
=
147 ( rVclWindowEvent
.GetId() == VCLEVENT_LISTBOX_ENTRY_EXPANDED
)
148 ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
149 : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED
;
150 uno::Any aListBoxEntry
;
151 aListBoxEntry
<<= xChild
;
152 NotifyAccessibleEvent( nAccEvent
, Any(), aListBoxEntry
);
153 if ( getListBox() && getListBox()->HasFocus() )
155 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, Any(), aListBoxEntry
);
163 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent
);
167 // -----------------------------------------------------------------------------
168 void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
170 switch ( rVclWindowEvent
.GetId() )
172 case VCLEVENT_WINDOW_SHOW
:
173 case VCLEVENT_WINDOW_HIDE
:
179 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
185 // -----------------------------------------------------------------------------
187 // -----------------------------------------------------------------------------
188 void SAL_CALL
AccessibleListBox::disposing()
190 ::osl::MutexGuard
aGuard( m_aMutex
);
192 VCLXAccessibleComponent::disposing();
195 // -----------------------------------------------------------------------------
197 // -----------------------------------------------------------------------------
198 ::rtl::OUString SAL_CALL
AccessibleListBox::getImplementationName() throw(RuntimeException
)
200 return getImplementationName_Static();
202 // -----------------------------------------------------------------------------
203 Sequence
< ::rtl::OUString
> SAL_CALL
AccessibleListBox::getSupportedServiceNames() throw(RuntimeException
)
205 return getSupportedServiceNames_Static();
207 // -----------------------------------------------------------------------------
208 sal_Bool SAL_CALL
AccessibleListBox::supportsService( const ::rtl::OUString
& _rServiceName
) throw (RuntimeException
)
210 Sequence
< ::rtl::OUString
> aSupported( getSupportedServiceNames() );
211 const ::rtl::OUString
* pSupported
= aSupported
.getConstArray();
212 const ::rtl::OUString
* pEnd
= pSupported
+ aSupported
.getLength();
213 for ( ; pSupported
!= pEnd
&& !pSupported
->equals(_rServiceName
); ++pSupported
)
216 return pSupported
!= pEnd
;
218 // -----------------------------------------------------------------------------
219 // XServiceInfo - static methods
220 // -----------------------------------------------------------------------------
221 Sequence
< ::rtl::OUString
> AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException
)
223 Sequence
< ::rtl::OUString
> aSupported(3);
224 aSupported
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
225 aSupported
[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
226 aSupported
[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") );
229 // -----------------------------------------------------------------------------
230 ::rtl::OUString
AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException
)
232 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") );
234 // -----------------------------------------------------------------------------
236 // -----------------------------------------------------------------------------
237 Reference
< XAccessibleContext
> SAL_CALL
AccessibleListBox::getAccessibleContext( ) throw (RuntimeException
)
242 // -----------------------------------------------------------------------------
243 // XAccessibleContext
244 // -----------------------------------------------------------------------------
245 sal_Int32 SAL_CALL
AccessibleListBox::getAccessibleChildCount( ) throw (RuntimeException
)
247 ::comphelper::OExternalLockGuard
aGuard( this );
251 sal_Int32 nCount
= 0;
252 SvTreeListBox
* pSvTreeListBox
= getListBox();
253 if ( pSvTreeListBox
)
254 nCount
= pSvTreeListBox
->GetLevelChildCount( NULL
);
258 // -----------------------------------------------------------------------------
259 Reference
< XAccessible
> SAL_CALL
AccessibleListBox::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
,RuntimeException
)
261 ::comphelper::OExternalLockGuard
aGuard( this );
264 SvLBoxEntry
* pEntry
= getListBox()->GetEntry(i
);
266 throw IndexOutOfBoundsException();
268 return new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
270 // -----------------------------------------------------------------------------
271 Reference
< XAccessible
> SAL_CALL
AccessibleListBox::getAccessibleParent( ) throw (RuntimeException
)
273 ::osl::MutexGuard
aGuard( m_aMutex
);
278 // -----------------------------------------------------------------------------
279 sal_Int16 SAL_CALL
AccessibleListBox::getAccessibleRole( ) throw (RuntimeException
)
281 return AccessibleRole::TREE
;
283 // -----------------------------------------------------------------------------
284 ::rtl::OUString SAL_CALL
AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException
)
286 ::comphelper::OExternalLockGuard
aGuard( this );
289 return getListBox()->GetAccessibleDescription();
291 // -----------------------------------------------------------------------------
292 ::rtl::OUString SAL_CALL
AccessibleListBox::getAccessibleName( ) throw (RuntimeException
)
294 ::comphelper::OExternalLockGuard
aGuard( this );
297 return getListBox()->GetAccessibleName();
299 // -----------------------------------------------------------------------------
300 // XAccessibleSelection
301 // -----------------------------------------------------------------------------
302 void SAL_CALL
AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
304 ::comphelper::OExternalLockGuard
aGuard( this );
308 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( nChildIndex
);
310 throw IndexOutOfBoundsException();
312 getListBox()->Select( pEntry
, TRUE
);
314 // -----------------------------------------------------------------------------
315 sal_Bool SAL_CALL
AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
317 ::comphelper::OExternalLockGuard
aGuard( this );
321 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( nChildIndex
);
323 throw IndexOutOfBoundsException();
325 return getListBox()->IsSelected( pEntry
);
327 // -----------------------------------------------------------------------------
328 void SAL_CALL
AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException
)
330 ::comphelper::OExternalLockGuard
aGuard( this );
334 sal_Int32 i
, nCount
= 0;
335 nCount
= getListBox()->GetLevelChildCount( NULL
);
336 for ( i
= 0; i
< nCount
; ++i
)
338 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( i
);
339 if ( getListBox()->IsSelected( pEntry
) )
340 getListBox()->Select( pEntry
, FALSE
);
343 // -----------------------------------------------------------------------------
344 void SAL_CALL
AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException
)
346 ::comphelper::OExternalLockGuard
aGuard( this );
350 sal_Int32 i
, nCount
= 0;
351 nCount
= getListBox()->GetLevelChildCount( NULL
);
352 for ( i
= 0; i
< nCount
; ++i
)
354 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( i
);
355 if ( !getListBox()->IsSelected( pEntry
) )
356 getListBox()->Select( pEntry
, TRUE
);
359 // -----------------------------------------------------------------------------
360 sal_Int32 SAL_CALL
AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException
)
362 ::comphelper::OExternalLockGuard
aGuard( this );
366 sal_Int32 i
, nSelCount
= 0, nCount
= 0;
367 nCount
= getListBox()->GetLevelChildCount( NULL
);
368 for ( i
= 0; i
< nCount
; ++i
)
370 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( i
);
371 if ( getListBox()->IsSelected( pEntry
) )
377 // -----------------------------------------------------------------------------
378 Reference
< XAccessible
> SAL_CALL
AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
380 ::comphelper::OExternalLockGuard
aGuard( this );
384 if ( nSelectedChildIndex
< 0 || nSelectedChildIndex
>= getSelectedAccessibleChildCount() )
385 throw IndexOutOfBoundsException();
387 Reference
< XAccessible
> xChild
;
388 sal_Int32 i
, nSelCount
= 0, nCount
= 0;
389 nCount
= getListBox()->GetLevelChildCount( NULL
);
390 for ( i
= 0; i
< nCount
; ++i
)
392 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( i
);
393 if ( getListBox()->IsSelected( pEntry
) )
396 if ( nSelCount
== ( nSelectedChildIndex
+ 1 ) )
398 xChild
= new AccessibleListBoxEntry( *getListBox(), pEntry
, this );
405 // -----------------------------------------------------------------------------
406 void SAL_CALL
AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
408 ::comphelper::OExternalLockGuard
aGuard( this );
412 SvLBoxEntry
* pEntry
= getListBox()->GetEntry( nSelectedChildIndex
);
414 throw IndexOutOfBoundsException();
416 getListBox()->Select( pEntry
, FALSE
);
418 // -----------------------------------------------------------------------------
419 void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
421 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
422 if ( getListBox() && isAlive() )
424 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
425 rStateSet
.AddState( AccessibleStateType::MANAGES_DESCENDANTS
);
426 if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION
)
427 rStateSet
.AddState( AccessibleStateType::MULTI_SELECTABLE
);
432 //........................................................................
433 }// namespace accessibility
434 //........................................................................