Branch data 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/svtreebx.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 <vcl/svapp.hxx>
30 : : #include <toolkit/awt/vclxwindow.hxx>
31 : : #include <toolkit/helper/convert.hxx>
32 : : #include <unotools/accessiblestatesethelper.hxx>
33 : :
34 : : //........................................................................
35 : : namespace accessibility
36 : : {
37 : : //........................................................................
38 : :
39 : : // class AccessibleListBox -----------------------------------------------------
40 : :
41 : : using namespace ::com::sun::star::accessibility;
42 : : using namespace ::com::sun::star::uno;
43 : : using namespace ::com::sun::star::lang;
44 : : using namespace ::com::sun::star;
45 : :
46 : : // -----------------------------------------------------------------------------
47 : : // Ctor() and Dtor()
48 : : // -----------------------------------------------------------------------------
49 : 6 : AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) :
50 : :
51 : : VCLXAccessibleComponent( _rListBox.GetWindowPeer() ),
52 [ + - ][ + - ]: 6 : m_xParent( _xParent )
53 : : {
54 : 6 : }
55 : : // -----------------------------------------------------------------------------
56 [ + - ]: 6 : AccessibleListBox::~AccessibleListBox()
57 : : {
58 [ + - ][ - + ]: 6 : if ( isAlive() )
59 : : {
60 : : // increment ref count to prevent double call of Dtor
61 [ # # ]: 0 : osl_incrementInterlockedCount( &m_refCount );
62 [ # # ]: 0 : dispose();
63 : : }
64 [ - + ]: 12 : }
65 [ + + ][ + - ]: 2846 : IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
66 [ # # ][ # # ]: 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
[ # # ]
67 : : // -----------------------------------------------------------------------------
68 : 270 : SvTreeListBox* AccessibleListBox::getListBox() const
69 : : {
70 : 270 : return static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() );
71 : : }
72 : : // -----------------------------------------------------------------------------
73 : 20 : void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
74 : : {
75 [ + - ]: 20 : if ( isAlive() )
76 : : {
77 [ - + - + ]: 20 : switch ( rVclWindowEvent.GetId() )
78 : : {
79 : : case VCLEVENT_CHECKBOX_TOGGLE :
80 : : {
81 [ # # ][ # # ]: 0 : if ( getListBox() && getListBox()->HasFocus() )
[ # # ]
82 : : {
83 : 0 : SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
84 [ # # ]: 0 : if ( !pEntry )
85 : 0 : pEntry = getListBox()->GetCurEntry();
86 : :
87 [ # # ]: 0 : if ( pEntry )
88 : : {
89 [ # # ][ # # ]: 0 : Reference< XAccessible > xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
[ # # ][ # # ]
[ # # ]
90 : 0 : uno::Any aOldValue, aNewValue;
91 [ # # ]: 0 : aNewValue <<= xChild;
92 [ # # ]: 0 : NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
93 : : }
94 : : }
95 : 0 : break;
96 : : }
97 : :
98 : : case VCLEVENT_LISTBOX_SELECT :
99 : : {
100 : : // First send an event that tells the listeners of a
101 : : // modified selection. The active descendant event is
102 : : // send after that so that the receiving AT has time to
103 : : // read the text or name of the active child.
104 [ + - ]: 2 : NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
105 [ + - ][ + - ]: 2 : if ( getListBox() && getListBox()->HasFocus() )
[ + - ]
106 : : {
107 : 2 : SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
108 [ + - ]: 2 : if ( pEntry )
109 : : {
110 [ + - ][ + - ]: 2 : Reference< XAccessible > xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
[ + - ][ + - ]
[ + - ]
111 : 2 : uno::Any aOldValue, aNewValue;
112 [ + - ]: 2 : aNewValue <<= xChild;
113 [ + - ]: 2 : NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
114 : : }
115 : : }
116 : 2 : break;
117 : :
118 : : // #i92103#
119 : : case VCLEVENT_ITEM_EXPANDED :
120 : : case VCLEVENT_ITEM_COLLAPSED :
121 : : {
122 : 0 : SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
123 [ # # ]: 0 : if ( pEntry )
124 : : {
125 : : AccessibleListBoxEntry* pAccListBoxEntry =
126 [ # # ][ # # ]: 0 : new AccessibleListBoxEntry( *getListBox(), pEntry, this );
[ # # ]
127 [ # # ][ # # ]: 0 : Reference< XAccessible > xChild = pAccListBoxEntry;
128 : : const short nAccEvent =
129 : 0 : ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED )
130 : : ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
131 [ # # ]: 0 : : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED;
132 : 0 : uno::Any aListBoxEntry;
133 [ # # ]: 0 : aListBoxEntry <<= xChild;
134 [ # # ]: 0 : NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry );
135 [ # # ][ # # ]: 0 : if ( getListBox() && getListBox()->HasFocus() )
[ # # ][ # # ]
[ # # ][ # # ]
136 : : {
137 [ # # ]: 0 : NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry );
138 : 0 : }
139 : : }
140 : 0 : break;
141 : : }
142 : : }
143 : : default:
144 : 20 : VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
145 : : }
146 : : }
147 : 20 : }
148 : : // -----------------------------------------------------------------------------
149 : 14 : void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
150 : : {
151 [ + + ]: 14 : switch ( rVclWindowEvent.GetId() )
152 : : {
153 : : case VCLEVENT_WINDOW_SHOW:
154 : : case VCLEVENT_WINDOW_HIDE:
155 : : {
156 : : }
157 : 6 : break;
158 : : default:
159 : : {
160 : 8 : VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
161 : : }
162 : 8 : break;
163 : : }
164 : 14 : }
165 : :
166 : : // -----------------------------------------------------------------------------
167 : : // XComponent
168 : : // -----------------------------------------------------------------------------
169 : 6 : void SAL_CALL AccessibleListBox::disposing()
170 : : {
171 [ + - ]: 6 : ::osl::MutexGuard aGuard( m_aMutex );
172 : :
173 [ + - ]: 6 : VCLXAccessibleComponent::disposing();
174 [ + - ][ + - ]: 6 : m_xParent = NULL;
175 : 6 : }
176 : : // -----------------------------------------------------------------------------
177 : : // XServiceInfo
178 : : // -----------------------------------------------------------------------------
179 : 0 : ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException)
180 : : {
181 : 0 : return getImplementationName_Static();
182 : : }
183 : : // -----------------------------------------------------------------------------
184 : 0 : Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException)
185 : : {
186 : 0 : return getSupportedServiceNames_Static();
187 : : }
188 : : // -----------------------------------------------------------------------------
189 : 0 : sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
190 : : {
191 [ # # ]: 0 : Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
192 : 0 : const ::rtl::OUString* pSupported = aSupported.getConstArray();
193 : 0 : const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
194 [ # # ][ # # ]: 0 : for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported )
[ # # ]
195 : : ;
196 : :
197 [ # # ]: 0 : return pSupported != pEnd;
198 : : }
199 : : // -----------------------------------------------------------------------------
200 : : // XServiceInfo - static methods
201 : : // -----------------------------------------------------------------------------
202 : 0 : Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException )
203 : : {
204 : 0 : Sequence< ::rtl::OUString > aSupported(3);
205 [ # # ][ # # ]: 0 : aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
206 [ # # ][ # # ]: 0 : aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
207 [ # # ][ # # ]: 0 : aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") );
208 : 0 : return aSupported;
209 : : }
210 : : // -----------------------------------------------------------------------------
211 : 0 : ::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException )
212 : : {
213 : 0 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") );
214 : : }
215 : : // -----------------------------------------------------------------------------
216 : : // XAccessible
217 : : // -----------------------------------------------------------------------------
218 : 132 : Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext( ) throw (RuntimeException)
219 : : {
220 : 132 : ensureAlive();
221 : 132 : return this;
222 : : }
223 : : // -----------------------------------------------------------------------------
224 : : // XAccessibleContext
225 : : // -----------------------------------------------------------------------------
226 : 12 : sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount( ) throw (RuntimeException)
227 : : {
228 [ + - ]: 12 : ::comphelper::OExternalLockGuard aGuard( this );
229 : :
230 [ + - ]: 12 : ensureAlive();
231 : :
232 : 12 : sal_Int32 nCount = 0;
233 [ + - ]: 12 : SvTreeListBox* pSvTreeListBox = getListBox();
234 [ + - ]: 12 : if ( pSvTreeListBox )
235 [ + - ]: 12 : nCount = pSvTreeListBox->GetLevelChildCount( NULL );
236 : :
237 [ + - ]: 12 : return nCount;
238 : : }
239 : : // -----------------------------------------------------------------------------
240 : 120 : Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
241 : : {
242 [ + - ]: 120 : ::comphelper::OExternalLockGuard aGuard( this );
243 : :
244 [ + - ]: 120 : ensureAlive();
245 [ + - ][ + - ]: 120 : SvLBoxEntry* pEntry = getListBox()->GetEntry(i);
246 [ - + ]: 120 : if ( !pEntry )
247 [ # # ]: 0 : throw IndexOutOfBoundsException();
248 : :
249 [ + - ][ + - ]: 120 : return new AccessibleListBoxEntry( *getListBox(), pEntry, this );
[ + - ][ + - ]
[ + - ][ + - ]
250 : : }
251 : : // -----------------------------------------------------------------------------
252 : 0 : Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent( ) throw (RuntimeException)
253 : : {
254 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
255 : :
256 [ # # ]: 0 : ensureAlive();
257 [ # # ]: 0 : return m_xParent;
258 : : }
259 : : // -----------------------------------------------------------------------------
260 : 12 : sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException)
261 : : {
262 : 12 : return AccessibleRole::TREE;
263 : : }
264 : : // -----------------------------------------------------------------------------
265 : 0 : ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException)
266 : : {
267 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
268 : :
269 [ # # ]: 0 : ensureAlive();
270 [ # # ][ # # ]: 0 : return getListBox()->GetAccessibleDescription();
[ # # ][ # # ]
[ # # ]
271 : : }
272 : : // -----------------------------------------------------------------------------
273 : 0 : ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName( ) throw (RuntimeException)
274 : : {
275 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
276 : :
277 [ # # ]: 0 : ensureAlive();
278 [ # # ][ # # ]: 0 : return getListBox()->GetAccessibleName();
[ # # ][ # # ]
[ # # ]
279 : : }
280 : : // -----------------------------------------------------------------------------
281 : : // XAccessibleSelection
282 : : // -----------------------------------------------------------------------------
283 : 0 : void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
284 : : {
285 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
286 : :
287 [ # # ]: 0 : ensureAlive();
288 : :
289 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
290 [ # # ]: 0 : if ( !pEntry )
291 [ # # ]: 0 : throw IndexOutOfBoundsException();
292 : :
293 [ # # ][ # # ]: 0 : getListBox()->Select( pEntry, sal_True );
[ # # ]
294 : 0 : }
295 : : // -----------------------------------------------------------------------------
296 : 0 : sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
297 : : {
298 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
299 : :
300 [ # # ]: 0 : ensureAlive();
301 : :
302 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
303 [ # # ]: 0 : if ( !pEntry )
304 [ # # ]: 0 : throw IndexOutOfBoundsException();
305 : :
306 [ # # ][ # # ]: 0 : return getListBox()->IsSelected( pEntry );
[ # # ]
307 : : }
308 : : // -----------------------------------------------------------------------------
309 : 0 : void SAL_CALL AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException)
310 : : {
311 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
312 : :
313 [ # # ]: 0 : ensureAlive();
314 : :
315 : 0 : sal_Int32 i, nCount = 0;
316 [ # # ][ # # ]: 0 : nCount = getListBox()->GetLevelChildCount( NULL );
317 [ # # ]: 0 : for ( i = 0; i < nCount; ++i )
318 : : {
319 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
320 [ # # ][ # # ]: 0 : if ( getListBox()->IsSelected( pEntry ) )
[ # # ]
321 [ # # ][ # # ]: 0 : getListBox()->Select( pEntry, sal_False );
322 [ # # ]: 0 : }
323 : 0 : }
324 : : // -----------------------------------------------------------------------------
325 : 0 : void SAL_CALL AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException)
326 : : {
327 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
328 : :
329 [ # # ]: 0 : ensureAlive();
330 : :
331 : 0 : sal_Int32 i, nCount = 0;
332 [ # # ][ # # ]: 0 : nCount = getListBox()->GetLevelChildCount( NULL );
333 [ # # ]: 0 : for ( i = 0; i < nCount; ++i )
334 : : {
335 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
336 [ # # ][ # # ]: 0 : if ( !getListBox()->IsSelected( pEntry ) )
[ # # ]
337 [ # # ][ # # ]: 0 : getListBox()->Select( pEntry, sal_True );
338 [ # # ]: 0 : }
339 : 0 : }
340 : : // -----------------------------------------------------------------------------
341 : 0 : sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException)
342 : : {
343 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
344 : :
345 [ # # ]: 0 : ensureAlive();
346 : :
347 : 0 : sal_Int32 i, nSelCount = 0, nCount = 0;
348 [ # # ][ # # ]: 0 : nCount = getListBox()->GetLevelChildCount( NULL );
349 [ # # ]: 0 : for ( i = 0; i < nCount; ++i )
350 : : {
351 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
352 [ # # ][ # # ]: 0 : if ( getListBox()->IsSelected( pEntry ) )
[ # # ]
353 : 0 : ++nSelCount;
354 : : }
355 : :
356 [ # # ]: 0 : return nSelCount;
357 : : }
358 : : // -----------------------------------------------------------------------------
359 : 0 : Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
360 : : {
361 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
362 : :
363 [ # # ]: 0 : ensureAlive();
364 : :
365 [ # # ][ # # ]: 0 : if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
[ # # ][ # # ]
366 [ # # ]: 0 : throw IndexOutOfBoundsException();
367 : :
368 : 0 : Reference< XAccessible > xChild;
369 : 0 : sal_Int32 i, nSelCount = 0, nCount = 0;
370 [ # # ][ # # ]: 0 : nCount = getListBox()->GetLevelChildCount( NULL );
371 [ # # ]: 0 : for ( i = 0; i < nCount; ++i )
372 : : {
373 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
374 [ # # ][ # # ]: 0 : if ( getListBox()->IsSelected( pEntry ) )
[ # # ]
375 : 0 : ++nSelCount;
376 : :
377 [ # # ]: 0 : if ( nSelCount == ( nSelectedChildIndex + 1 ) )
378 : : {
379 [ # # ][ # # ]: 0 : xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
[ # # ][ # # ]
[ # # ]
380 : 0 : break;
381 : : }
382 : : }
383 : :
384 [ # # ]: 0 : return xChild;
385 : : }
386 : : // -----------------------------------------------------------------------------
387 : 0 : void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
388 : : {
389 [ # # ]: 0 : ::comphelper::OExternalLockGuard aGuard( this );
390 : :
391 [ # # ]: 0 : ensureAlive();
392 : :
393 [ # # ][ # # ]: 0 : SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex );
394 [ # # ]: 0 : if ( !pEntry )
395 [ # # ]: 0 : throw IndexOutOfBoundsException();
396 : :
397 [ # # ][ # # ]: 0 : getListBox()->Select( pEntry, sal_False );
[ # # ]
398 : 0 : }
399 : : // -----------------------------------------------------------------------------
400 : 6 : void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
401 : : {
402 : 6 : VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
403 [ + - ][ + - ]: 6 : if ( getListBox() && isAlive() )
[ + - ]
404 : : {
405 : 6 : rStateSet.AddState( AccessibleStateType::FOCUSABLE );
406 : 6 : rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
407 [ - + ]: 6 : if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION )
408 : 0 : rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
409 : : }
410 : 6 : }
411 : :
412 : :
413 : : //........................................................................
414 : : }// namespace accessibility
415 : : //........................................................................
416 : :
417 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|