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 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 62 AccessibleGridControlTable::~AccessibleGridControlTable() 63 { 64 } 65 66 // XAccessibleContext --------------------------------------------------------- 67 68 Reference< XAccessible > SAL_CALL 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 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 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 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 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 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 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 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 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 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 190 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns() 191 throw ( uno::RuntimeException ) 192 { 193 Sequence< sal_Int32 > aSelSeq(0); 194 return aSelSeq; 195 } 196 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 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 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 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 } 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 } 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 } 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 } 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 } 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 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 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 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 343 void SAL_CALL AccessibleGridControlTable::acquire() throw () 344 { 345 AccessibleGridControlTableBase::acquire(); 346 } 347 348 void SAL_CALL AccessibleGridControlTable::release() throw () 349 { 350 AccessibleGridControlTableBase::release(); 351 } 352 // XServiceInfo --------------------------------------------------------------- 353 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 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 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 ---------------------------------------------------- 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 409 std::vector< AccessibleGridControlTableCell* >& AccessibleGridControlTable::getCellVector() 410 { 411 return m_pCellVector; 412 } 413 414 std::vector< Reference< XAccessible > >& AccessibleGridControlTable::getAccessibleCellVector() 415 { 416 return m_pAccessCellVector; 417 } 418 // ============================================================================ 419 420 } // namespace accessibility 421 422 // ============================================================================ 423 424