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