LibreOffice Module accessibility (master) 1
accessibletablistboxtable.cxx
Go to the documentation of this file.
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
23#include <com/sun/star/accessibility/AccessibleEventId.hpp>
24#include <com/sun/star/accessibility/AccessibleStateType.hpp>
25#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27
28namespace accessibility
29{
30
31
32 // class AccessibleTabListBoxTable ---------------------------------------------
33
34 using namespace ::com::sun::star::accessibility;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star;
38
39
40 // Ctor() and Dtor()
41
43
44 AccessibleBrowseBoxTable( rxParent, rBox ),
45
46 m_pTabListBox ( &rBox )
47
48 {
49 m_pTabListBox->AddEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) );
50 }
51
53 {
54 if ( isAlive() )
55 {
56 m_pTabListBox = nullptr;
57
58 // increment ref count to prevent double call of Dtor
59 osl_atomic_increment( &m_refCount );
60 dispose();
61 }
62 }
63
65 {
66 if ( !isAlive() )
67 return;
68
69 switch ( VclEventId nEventId = rVclWindowEvent.GetId(); nEventId )
70 {
71 case VclEventId::ObjectDying :
72 {
73 m_pTabListBox->RemoveEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) );
74 m_pTabListBox = nullptr;
75 break;
76 }
77
78 case VclEventId::ControlGetFocus :
79 case VclEventId::ControlLoseFocus :
80 {
81 uno::Any aOldValue, aNewValue;
82 if ( nEventId == VclEventId::ControlGetFocus )
83 aNewValue <<= AccessibleStateType::FOCUSED;
84 else
85 aOldValue <<= AccessibleStateType::FOCUSED;
86 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue );
87 break;
88 }
89
90 case VclEventId::ListboxSelect :
91 {
92 // First send an event that tells the listeners of a
93 // modified selection. The active descendant event is
94 // send after that so that the receiving AT has time to
95 // read the text or name of the active child.
96 commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
97 if ( m_pTabListBox && m_pTabListBox->HasFocus() )
98 {
99 SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() );
100 if ( pEntry )
101 {
102 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry );
103 sal_uInt16 nCol = m_pTabListBox->GetCurrColumn();
105 m_pTabListBox->CreateAccessibleCell( nRow, nCol );
106 uno::Any aOldValue, aNewValue;
107 aNewValue <<= xChild;
108 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue, aOldValue );
109 }
110 }
111 break;
112 }
113 case VclEventId::WindowGetFocus :
114 {
115 uno::Any aOldValue, aNewValue;
116 aNewValue <<= AccessibleStateType::FOCUSED;
117 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue );
118 break;
119
120 }
121 case VclEventId::WindowLoseFocus :
122 {
123 uno::Any aOldValue, aNewValue;
124 aOldValue <<= AccessibleStateType::FOCUSED;
125 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue );
126 break;
127 }
128 case VclEventId::ListboxTreeSelect:
129 {
130 SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() );
131 if (pEntry)
132 {
133 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry );
134 Reference< XAccessible > xChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() );
135 TriState eState = TRISTATE_INDET;
136 if ( m_pTabListBox->IsCellCheckBox( nRow, m_pTabListBox->GetCurrColumn(), eState ) )
137 {
138 AccessibleCheckBoxCell* pCell = static_cast< AccessibleCheckBoxCell* >( xChild.get() );
139 pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
140 }
141 else
142 {
143 AccessibleBrowseBoxTableCell* pCell = static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() );
144 pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
145 }
146 }
147 }
148 break;
149 case VclEventId::ListboxTreeFocus:
150 {
151 if ( m_pTabListBox && m_pTabListBox->HasFocus() )
152 {
153 uno::Any aOldValue, aNewValue;
154 SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() );
155 if ( pEntry )
156 {
157 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry );
158 m_xCurChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() );
159 aNewValue <<= m_xCurChild;
160 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue ,aOldValue);
161 }
162 else
163 {
164 aNewValue <<= AccessibleStateType::FOCUSED;
165 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue ,aOldValue);
166 }
167 }
168 }
169 break;
170
171 case VclEventId::CheckboxToggle :
172 {
173 if ( m_pTabListBox && m_pTabListBox->HasFocus() )
174 {
175 SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() );
176 if ( pEntry )
177 {
178 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry );
179 sal_uInt16 nCol = m_pTabListBox->GetCurrColumn();
180 TriState eState = TRISTATE_INDET;
181 if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) )
182 {
184 m_pTabListBox->CreateAccessibleCell( nRow, nCol );
186 static_cast< AccessibleCheckBoxCell* >( xChild.get() );
187 pCell->SetChecked( SvHeaderTabListBox::IsItemChecked( pEntry, nCol ) );
188 }
189 }
190 }
191 break;
192 }
193
194 default: break;
195 }
196 }
197
198 IMPL_LINK( AccessibleTabListBoxTable, WindowEventListener, VclWindowEvent&, rEvent, void )
199 {
200 OSL_ENSURE( rEvent.GetWindow() && m_pTabListBox, "no event window" );
201 ProcessWindowEvent( rEvent );
202 }
203 // helpers --------------------------------------------------------------------
204
205 void AccessibleTabListBoxTable::ensureValidIndex( sal_Int64 _nIndex ) const
206 {
207 if ( ( _nIndex < 0 ) || ( _nIndex >= static_cast<sal_Int64>((implGetRowCount()) * static_cast<sal_Int64>(implGetColumnCount()))))
208 throw IndexOutOfBoundsException();
209 }
210
211 void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow, bool _bSelect )
212 {
213 if ( m_pTabListBox )
214 m_pTabListBox->SelectRow(_nRow, _bSelect);
215 }
216
218 {
219 return m_pTabListBox ? m_pTabListBox->GetEntryCount() : 0;
220 }
221
223 {
224 return m_pTabListBox ? m_pTabListBox->GetColumnCount() : 0;
225 }
226
228 {
229 return m_pTabListBox ? m_pTabListBox->GetSelectionCount() : 0;
230 }
231
232 sal_Int32 AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow ) const
233 {
234 if ( m_pTabListBox )
235 {
236 sal_Int32 nRow = 0;
237 SvTreeListEntry* pEntry = m_pTabListBox->FirstSelected();
238 while ( pEntry )
239 {
240 if ( nRow == nSelRow )
241 return m_pTabListBox->GetEntryPos( pEntry );
242 pEntry = m_pTabListBox->NextSelected( pEntry );
243 ++nRow;
244 }
245 }
246
247 return 0;
248 }
249
250 // XInterface & XTypeProvider
251
254
255 // XServiceInfo
256
257 OUString AccessibleTabListBoxTable::getImplementationName()
258 {
259 return "com.sun.star.comp.svtools.AccessibleTabListBoxTable";
260 }
261
262 // XAccessibleSelection
263
264 void SAL_CALL AccessibleTabListBoxTable::selectAccessibleChild( sal_Int64 nChildIndex )
265 {
266 SolarMutexGuard aSolarGuard;
267 ::osl::MutexGuard aGuard( getMutex() );
268
270 ensureValidIndex( nChildIndex );
271
272 implSelectRow( implGetRow( nChildIndex ), true );
273 }
274
276 {
277 SolarMutexGuard aSolarGuard;
278 ::osl::MutexGuard aGuard( getMutex() );
279
281 ensureValidIndex( nChildIndex );
282
283 return m_pTabListBox && m_pTabListBox->IsRowSelected(implGetRow(nChildIndex));
284 }
285
287 {
288 SolarMutexGuard aSolarGuard;
289 ::osl::MutexGuard aGuard( getMutex() );
290
292
293 m_pTabListBox->SetNoSelection();
294 }
295
297 {
298 SolarMutexGuard aSolarGuard;
299 ::osl::MutexGuard aGuard( getMutex() );
300
302
303 m_pTabListBox->SelectAll();
304 }
305
307 {
308 SolarMutexGuard aSolarGuard;
309 ::osl::MutexGuard aGuard( getMutex() );
310
312
313 return static_cast<sal_Int64>(implGetColumnCount()) * static_cast<sal_Int64>(implGetSelRowCount());
314 }
315
317 {
318 SolarMutexGuard aSolarGuard;
319 ::osl::MutexGuard aGuard( getMutex() );
320
322
323 const sal_Int32 nColCount = implGetColumnCount();
324
325 if (nColCount == 0)
326 throw IndexOutOfBoundsException();
327
328 const sal_Int32 nRow = implGetSelRow(nSelectedChildIndex / nColCount);
329 const sal_Int32 nColumn = nSelectedChildIndex % nColCount;
330 return getAccessibleCellAt( nRow, nColumn );
331 }
332
333 void SAL_CALL AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int64 nSelectedChildIndex )
334 {
335 SolarMutexGuard aSolarGuard;
336 ::osl::MutexGuard aGuard( getMutex() );
337
339 ensureValidIndex( nSelectedChildIndex );
340
341 implSelectRow( implGetRow( nSelectedChildIndex ), false );
342 }
343
344
345}// namespace accessibility
346
347
348/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool IsItemChecked(SvTreeListEntry *pEntry, sal_uInt16 nCol)
VclEventId GetId() const
void * GetData() const
void commitEvent(sal_Int16 nEventId, const css::uno::Any &rNewValue, const css::uno::Any &rOldValue)
Commits an event to all listeners.
This class represents the accessible object of the data table of a BrowseBox control.
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn) override
sal_Int64 SAL_CALL getSelectedAccessibleChildCount() override
AccessibleTabListBoxTable(const css::uno::Reference< css::accessibility::XAccessible > &rxParent, SvHeaderTabListBox &rBox)
ctor()
sal_Int32 implGetSelRow(sal_Int32 _nSelRow) const
Returns the absolute row index of the nSelRow-th selected row.
css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int64 nSelectedChildIndex) override
void SAL_CALL deselectAccessibleChild(sal_Int64 nSelectedChildIndex) override
sal_Int32 implGetSelRowCount() const
Returns the count of selected rows in the table.
sal_Int32 implGetColumnCount() const override
Returns the total column count in the table.
void SAL_CALL selectAccessibleChild(sal_Int64 nChildIndex) override
sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int64 nChildIndex) override
void implSelectRow(sal_Int32 _nRow, bool _bSelect)
Selects the specified row.
sal_Int32 implGetRowCount() const override
Returns the count of rows in the table.
void ProcessWindowEvent(const VclWindowEvent &rVclWindowEvent)
css::uno::Reference< css::accessibility::XAccessible > m_xCurChild
void ensureValidIndex(sal_Int64 _nIndex) const
Throws an exception, if nIndex is not a valid child index.
sal_Int32 implGetRow(sal_Int64 _nIndex) const
Returns the row index from cell index.
ULONG m_refCount
TriState
TRISTATE_INDET
IMPL_LINK(AccessibleDocumentViewBase, WindowChildEventListener, VclWindowEvent &, rEvent, void)
IMPLEMENT_FORWARD_XTYPEPROVIDER2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
IMPLEMENT_FORWARD_XINTERFACE2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
void dispose()
unsigned char sal_Bool
VclEventId