1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26
27
28 #include "accessibility/extended/AccessibleGridControlTable.hxx"
29 #include "accessibility/extended/AccessibleGridControlTableCell.hxx"
30 #include <svtools/accessibletable.hxx>
31
32 // ============================================================================
33
34 using ::rtl::OUString;
35
36 using ::com::sun::star::uno::Reference;
37 using ::com::sun::star::uno::Sequence;
38 using ::com::sun::star::uno::Any;
39
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::accessibility;
42 using namespace ::svt;
43 using namespace ::svt::table;
44 // ============================================================================
45
46 namespace accessibility {
47
48 // ============================================================================
49
DBG_NAME(AccessibleGridControlTable)50 DBG_NAME( AccessibleGridControlTable )
51
52 AccessibleGridControlTable::AccessibleGridControlTable(
53 const Reference< XAccessible >& rxParent,
54 IAccessibleTable& rTable,
55 AccessibleTableControlObjType _eType) :
56 AccessibleGridControlTableBase( rxParent, rTable, _eType )
57 ,m_pCellVector( )
58 ,m_pAccessCellVector( )
59 {
60 }
61
~AccessibleGridControlTable()62 AccessibleGridControlTable::~AccessibleGridControlTable()
63 {
64 }
65
66 // XAccessibleContext ---------------------------------------------------------
67
68 Reference< XAccessible > SAL_CALL
getAccessibleChild(sal_Int32 nChildIndex)69 AccessibleGridControlTable::getAccessibleChild( sal_Int32 nChildIndex )
70 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
71 {
72 TCSolarGuard aSolarGuard;
73 ::osl::MutexGuard aGuard( getOslMutex() );
74 ensureIsAlive();
75 ensureIsValidIndex( nChildIndex );
76 sal_Int32 nCount = getAccessibleChildCount();
77 if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount)
78 {
79 m_pAccessCellVector.resize(nCount);
80 m_pCellVector.resize(nCount);
81 }
82 if(!m_pAccessCellVector[nChildIndex].is())
83 {
84 AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount(), TCTYPE_TABLECELL);
85 m_pCellVector[nChildIndex] = pCell;
86 m_pAccessCellVector[nChildIndex] = pCell;
87 }
88 return m_pAccessCellVector[nChildIndex];
89 }
90
getAccessibleIndexInParent()91 sal_Int32 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent()
92 throw ( uno::RuntimeException )
93 {
94 ensureIsAlive();
95 if(m_aTable.HasRowHeader() && m_aTable.HasColHeader())
96 return 0;
97 else if((!m_aTable.HasRowHeader() && m_aTable.HasColHeader()) || (m_aTable.HasRowHeader() && !m_aTable.HasColHeader()) )
98 return 1;
99 else
100 return 2;
101 }
102
103 // XAccessibleComponent -------------------------------------------------------
104
105 Reference< XAccessible > SAL_CALL
getAccessibleAtPoint(const awt::Point & rPoint)106 AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint )
107 throw ( uno::RuntimeException )
108 {
109 TCSolarGuard aSolarGuard;
110 ::osl::MutexGuard aGuard( getOslMutex() );
111 ensureIsAlive();
112
113 Reference< XAccessible > xChild;
114 sal_Int32 nRow = 0;
115 sal_Int32 nColumnPos = 0;
116 if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) )
117 xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos, TCTYPE_TABLECELL);
118 return xChild;
119 }
120
grabFocus()121 void SAL_CALL AccessibleGridControlTable::grabFocus()
122 throw ( uno::RuntimeException )
123 {
124 TCSolarGuard aSolarGuard;
125 ::osl::MutexGuard aGuard( getOslMutex() );
126 ensureIsAlive();
127 m_aTable.GrabFocus();
128 }
129
getAccessibleKeyBinding()130 Any SAL_CALL AccessibleGridControlTable::getAccessibleKeyBinding()
131 throw ( uno::RuntimeException )
132 {
133 ensureIsAlive();
134 return Any(); // no special key bindings for data table
135 }
136
137 // XAccessibleTable -----------------------------------------------------------
138
getAccessibleRowDescription(sal_Int32 nRow)139 OUString SAL_CALL AccessibleGridControlTable::getAccessibleRowDescription( sal_Int32 nRow )
140 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
141 {
142 TCSolarGuard aSolarGuard;
143 ::osl::MutexGuard aGuard( getOslMutex() );
144 ensureIsAlive();
145 ensureIsValidRow( nRow );
146 return m_aTable.GetRowDescription( nRow );
147 }
148
getAccessibleColumnDescription(sal_Int32 nColumn)149 OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn )
150 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
151 {
152 TCSolarGuard aSolarGuard;
153 ::osl::MutexGuard aGuard( getOslMutex() );
154 ensureIsAlive();
155 ensureIsValidColumn( nColumn );
156 return m_aTable.GetColumnDescription( (sal_uInt16)nColumn );
157 }
158
getAccessibleRowHeaders()159 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleRowHeaders()
160 throw ( uno::RuntimeException )
161 {
162 ::osl::MutexGuard aGuard( getOslMutex() );
163 ensureIsAlive();
164 if(m_aTable.HasColHeader())
165 return implGetHeaderBar( 1 );
166 else
167 return implGetHeaderBar( 0 );
168 }
169
getAccessibleColumnHeaders()170 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleColumnHeaders()
171 throw ( uno::RuntimeException )
172 {
173 ::osl::MutexGuard aGuard( getOslMutex() );
174 ensureIsAlive();
175 return implGetHeaderBar( 0 );
176 }
177
getSelectedAccessibleRows()178 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleRows()
179 throw ( uno::RuntimeException )
180 {
181 TCSolarGuard aSolarGuard;
182 ::osl::MutexGuard aGuard( getOslMutex() );
183 ensureIsAlive();
184 Sequence< sal_Int32 > aSelSeq;
185 implGetSelectedRows( aSelSeq );
186 return aSelSeq;
187 }
188
189 //columns aren't selectable
getSelectedAccessibleColumns()190 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns()
191 throw ( uno::RuntimeException )
192 {
193 Sequence< sal_Int32 > aSelSeq(0);
194 return aSelSeq;
195 }
196
isAccessibleRowSelected(sal_Int32 nRow)197 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleRowSelected( sal_Int32 nRow )
198 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
199 {
200 TCSolarGuard aSolarGuard;
201 ::osl::MutexGuard aGuard( getOslMutex() );
202 ensureIsAlive();
203 ensureIsValidRow( nRow );
204 sal_Bool bSelected = sal_False;
205 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
206 for(int i=0; i<selectedRows.getLength(); i++)
207 {
208 if(nRow == selectedRows[i])
209 {
210 bSelected = sal_True;
211 continue;
212 }
213 }
214 return bSelected;
215 }
216
217 //columns aren't selectable
isAccessibleColumnSelected(sal_Int32 nColumn)218 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleColumnSelected( sal_Int32 nColumn )
219 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
220 {
221 (void) nColumn;
222 return sal_False;
223 }
224
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)225 Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellAt(
226 sal_Int32 nRow, sal_Int32 nColumn )
227 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
228 {
229 TCSolarGuard aSolarGuard;
230 ::osl::MutexGuard aGuard( getOslMutex() );
231 ensureIsAlive();
232 ensureIsValidAddress( nRow, nColumn );
233 sal_Int32 nCount = getAccessibleChildCount();
234 sal_Int32 nChildIndex = nRow*m_aTable.GetColumnCount() + nColumn;
235 if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount)
236 {
237 m_pAccessCellVector.resize(nCount);
238 m_pCellVector.resize(nCount);
239 }
240 if(!m_pAccessCellVector[nChildIndex].is())
241 {
242 AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumn, TCTYPE_TABLECELL);
243 m_pCellVector[nChildIndex] = pCell;
244 m_pAccessCellVector[nChildIndex] = pCell;
245 }
246 return m_pAccessCellVector[nChildIndex];
247 }
248
isAccessibleSelected(sal_Int32 nRow,sal_Int32 nColumn)249 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected(
250 sal_Int32 nRow, sal_Int32 nColumn )
251 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
252 {
253 TCSolarGuard aSolarGuard;
254 ::osl::MutexGuard aGuard( getOslMutex() );
255 ensureIsAlive();
256 ensureIsValidAddress( nRow, nColumn );
257 (void) nColumn;
258 //selection of single cells not possible, so if row is selected, the cell will be selected too
259 return isAccessibleRowSelected(nRow);
260 }
selectAccessibleChild(sal_Int32 nChildIndex)261 void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int32 nChildIndex )
262 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
263 {
264 TCSolarGuard aSolarGuard;
265 ::osl::MutexGuard aGuard( getOslMutex() );
266 ensureIsAlive();
267 ensureIsValidIndex( nChildIndex );
268 sal_Int32 nColumns = m_aTable.GetColumnCount();
269 sal_Int32 nRow = (nChildIndex / nColumns);
270 m_aTable.SelectRow( nRow, sal_True );
271 }
isAccessibleChildSelected(sal_Int32 nChildIndex)272 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleChildSelected( sal_Int32 nChildIndex )
273 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
274 {
275 TCSolarGuard aSolarGuard;
276 ::osl::MutexGuard aGuard( getOslMutex() );
277 ensureIsAlive();
278 ensureIsValidIndex( nChildIndex );
279 sal_Int32 nColumns = m_aTable.GetColumnCount();
280 sal_Int32 nRow = (nChildIndex / nColumns);
281 return isAccessibleRowSelected(nRow);
282 }
clearAccessibleSelection()283 void SAL_CALL AccessibleGridControlTable::clearAccessibleSelection()
284 throw ( uno::RuntimeException )
285 {
286 TCSolarGuard aSolarGuard;
287 ::osl::MutexGuard aGuard( getOslMutex() );
288 ensureIsAlive();
289 m_aTable.SelectAllRows( false );
290 }
selectAllAccessibleChildren()291 void SAL_CALL AccessibleGridControlTable::selectAllAccessibleChildren()
292 throw ( uno::RuntimeException )
293 {
294 TCSolarGuard aSolarGuard;
295 ::osl::MutexGuard aGuard( getOslMutex() );
296 ensureIsAlive();
297 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
298 for(int i=0;i<m_aTable.GetRowCount();i++)
299 selectedRows[i]=i;
300 }
getSelectedAccessibleChildCount()301 sal_Int32 SAL_CALL AccessibleGridControlTable::getSelectedAccessibleChildCount()
302 throw ( uno::RuntimeException )
303 {
304 TCSolarGuard aSolarGuard;
305 ::osl::MutexGuard aGuard( getOslMutex() );
306 ensureIsAlive();
307 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
308 sal_Int32 nColumns = m_aTable.GetColumnCount();
309 return selectedRows.getLength()*nColumns;
310 }
311 Reference< XAccessible > SAL_CALL
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)312 AccessibleGridControlTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
313 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
314 {
315 TCSolarGuard aSolarGuard;
316 ::osl::MutexGuard aGuard( getOslMutex() );
317 ensureIsAlive();
318 if(isAccessibleChildSelected(nSelectedChildIndex))
319 return getAccessibleChild(nSelectedChildIndex);
320 else
321 return NULL;
322 }
323 //not implemented yet, because only row selection possible
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)324 void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild(
325 sal_Int32 nSelectedChildIndex )
326 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
327 {
328 TCSolarGuard aSolarGuard;
329 ::osl::MutexGuard aGuard( getOslMutex() );
330 ensureIsAlive();
331 (void)nSelectedChildIndex;
332 }
333 // XInterface -----------------------------------------------------------------
334
queryInterface(const uno::Type & rType)335 Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType )
336 throw ( uno::RuntimeException )
337 {
338 Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) );
339 return aAny.hasValue() ?
340 aAny : AccessibleGridControlTableImplHelper1::queryInterface( rType );
341 }
342
acquire()343 void SAL_CALL AccessibleGridControlTable::acquire() throw ()
344 {
345 AccessibleGridControlTableBase::acquire();
346 }
347
release()348 void SAL_CALL AccessibleGridControlTable::release() throw ()
349 {
350 AccessibleGridControlTableBase::release();
351 }
352 // XServiceInfo ---------------------------------------------------------------
353
getImplementationName()354 OUString SAL_CALL AccessibleGridControlTable::getImplementationName()
355 throw ( uno::RuntimeException )
356 {
357 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTable" ) );
358 }
359
360 // internal virtual methods ---------------------------------------------------
361
implGetBoundingBox()362 Rectangle AccessibleGridControlTable::implGetBoundingBox()
363 {
364 Window* pParent = m_aTable.GetAccessibleParentWindow();
365 DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
366 Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent ));
367 Rectangle aTableRect( m_aTable.calcTableRect() );
368 long nX = aGridRect.Left() + aTableRect.Left();
369 long nY = aGridRect.Top() + aTableRect.Top();
370 long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
371 long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
372 Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
373 return aTable;
374 }
375
implGetBoundingBoxOnScreen()376 Rectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen()
377 {
378 Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( NULL ));
379 Rectangle aTableRect( m_aTable.calcTableRect() );
380 long nX = aGridRect.Left() + aTableRect.Left();
381 long nY = aGridRect.Top() + aTableRect.Top();
382 long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
383 long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
384 Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
385 return aTable;
386 }
387 // internal helper methods ----------------------------------------------------
implGetHeaderBar(sal_Int32 nChildIndex)388 Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar(
389 sal_Int32 nChildIndex )
390 throw ( uno::RuntimeException )
391 {
392 Reference< XAccessible > xRet;
393 Reference< XAccessibleContext > xContext( m_xParent, uno::UNO_QUERY );
394 if( xContext.is() )
395 {
396 try
397 {
398 xRet = xContext->getAccessibleChild( nChildIndex );
399 }
400 catch( lang::IndexOutOfBoundsException& )
401 {
402 DBG_ERROR( "implGetHeaderBar - wrong child index" );
403 }
404 // RuntimeException goes to caller
405 }
406 return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY );
407 }
408
getCellVector()409 std::vector< AccessibleGridControlTableCell* >& AccessibleGridControlTable::getCellVector()
410 {
411 return m_pCellVector;
412 }
413
getAccessibleCellVector()414 std::vector< Reference< XAccessible > >& AccessibleGridControlTable::getAccessibleCellVector()
415 {
416 return m_pAccessCellVector;
417 }
418 // ============================================================================
419
420 } // namespace accessibility
421
422 // ============================================================================
423
424