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 { 71 TCSolarGuard aSolarGuard; 72 ::osl::MutexGuard aGuard( getOslMutex() ); 73 ensureIsAlive(); 74 ensureIsValidIndex( nChildIndex ); 75 sal_Int32 nCount = getAccessibleChildCount(); 76 if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount) 77 { 78 m_pAccessCellVector.resize(nCount); 79 m_pCellVector.resize(nCount); 80 } 81 if(!m_pAccessCellVector[nChildIndex].is()) 82 { 83 AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount(), TCTYPE_TABLECELL); 84 m_pCellVector[nChildIndex] = pCell; 85 m_pAccessCellVector[nChildIndex] = pCell; 86 } 87 return m_pAccessCellVector[nChildIndex]; 88 } 89 90 sal_Int32 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent() 91 { 92 ensureIsAlive(); 93 if(m_aTable.HasRowHeader() && m_aTable.HasColHeader()) 94 return 0; 95 else if((!m_aTable.HasRowHeader() && m_aTable.HasColHeader()) || (m_aTable.HasRowHeader() && !m_aTable.HasColHeader()) ) 96 return 1; 97 else 98 return 2; 99 } 100 101 // XAccessibleComponent ------------------------------------------------------- 102 103 Reference< XAccessible > SAL_CALL 104 AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint ) 105 { 106 TCSolarGuard aSolarGuard; 107 ::osl::MutexGuard aGuard( getOslMutex() ); 108 ensureIsAlive(); 109 110 Reference< XAccessible > xChild; 111 sal_Int32 nRow = 0; 112 sal_Int32 nColumnPos = 0; 113 if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) ) 114 xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos, TCTYPE_TABLECELL); 115 return xChild; 116 } 117 118 void SAL_CALL AccessibleGridControlTable::grabFocus() 119 { 120 TCSolarGuard aSolarGuard; 121 ::osl::MutexGuard aGuard( getOslMutex() ); 122 ensureIsAlive(); 123 m_aTable.GrabFocus(); 124 } 125 126 Any SAL_CALL AccessibleGridControlTable::getAccessibleKeyBinding() 127 { 128 ensureIsAlive(); 129 return Any(); // no special key bindings for data table 130 } 131 132 // XAccessibleTable ----------------------------------------------------------- 133 134 OUString SAL_CALL AccessibleGridControlTable::getAccessibleRowDescription( sal_Int32 nRow ) 135 { 136 TCSolarGuard aSolarGuard; 137 ::osl::MutexGuard aGuard( getOslMutex() ); 138 ensureIsAlive(); 139 ensureIsValidRow( nRow ); 140 return m_aTable.GetRowDescription( nRow ); 141 } 142 143 OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn ) 144 { 145 TCSolarGuard aSolarGuard; 146 ::osl::MutexGuard aGuard( getOslMutex() ); 147 ensureIsAlive(); 148 ensureIsValidColumn( nColumn ); 149 return m_aTable.GetColumnDescription( (sal_uInt16)nColumn ); 150 } 151 152 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleRowHeaders() 153 { 154 ::osl::MutexGuard aGuard( getOslMutex() ); 155 ensureIsAlive(); 156 if(m_aTable.HasColHeader()) 157 return implGetHeaderBar( 1 ); 158 else 159 return implGetHeaderBar( 0 ); 160 } 161 162 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleColumnHeaders() 163 { 164 ::osl::MutexGuard aGuard( getOslMutex() ); 165 ensureIsAlive(); 166 return implGetHeaderBar( 0 ); 167 } 168 169 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleRows() 170 { 171 TCSolarGuard aSolarGuard; 172 ::osl::MutexGuard aGuard( getOslMutex() ); 173 ensureIsAlive(); 174 Sequence< sal_Int32 > aSelSeq; 175 implGetSelectedRows( aSelSeq ); 176 return aSelSeq; 177 } 178 179 //columns aren't selectable 180 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns() 181 { 182 Sequence< sal_Int32 > aSelSeq(0); 183 return aSelSeq; 184 } 185 186 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleRowSelected( sal_Int32 nRow ) 187 { 188 TCSolarGuard aSolarGuard; 189 ::osl::MutexGuard aGuard( getOslMutex() ); 190 ensureIsAlive(); 191 ensureIsValidRow( nRow ); 192 sal_Bool bSelected = sal_False; 193 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); 194 for(int i=0; i<selectedRows.getLength(); i++) 195 { 196 if(nRow == selectedRows[i]) 197 { 198 bSelected = sal_True; 199 continue; 200 } 201 } 202 return bSelected; 203 } 204 205 //columns aren't selectable 206 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleColumnSelected( sal_Int32 nColumn ) 207 { 208 (void) nColumn; 209 return sal_False; 210 } 211 212 Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellAt( 213 sal_Int32 nRow, sal_Int32 nColumn ) 214 { 215 TCSolarGuard aSolarGuard; 216 ::osl::MutexGuard aGuard( getOslMutex() ); 217 ensureIsAlive(); 218 ensureIsValidAddress( nRow, nColumn ); 219 sal_Int32 nCount = getAccessibleChildCount(); 220 sal_Int32 nChildIndex = nRow*m_aTable.GetColumnCount() + nColumn; 221 if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount) 222 { 223 m_pAccessCellVector.resize(nCount); 224 m_pCellVector.resize(nCount); 225 } 226 if(!m_pAccessCellVector[nChildIndex].is()) 227 { 228 AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumn, TCTYPE_TABLECELL); 229 m_pCellVector[nChildIndex] = pCell; 230 m_pAccessCellVector[nChildIndex] = pCell; 231 } 232 return m_pAccessCellVector[nChildIndex]; 233 } 234 235 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected( 236 sal_Int32 nRow, sal_Int32 nColumn ) 237 { 238 TCSolarGuard aSolarGuard; 239 ::osl::MutexGuard aGuard( getOslMutex() ); 240 ensureIsAlive(); 241 ensureIsValidAddress( nRow, nColumn ); 242 (void) nColumn; 243 //selection of single cells not possible, so if row is selected, the cell will be selected too 244 return isAccessibleRowSelected(nRow); 245 } 246 void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int32 nChildIndex ) 247 { 248 TCSolarGuard aSolarGuard; 249 ::osl::MutexGuard aGuard( getOslMutex() ); 250 ensureIsAlive(); 251 ensureIsValidIndex( nChildIndex ); 252 sal_Int32 nColumns = m_aTable.GetColumnCount(); 253 sal_Int32 nRow = (nChildIndex / nColumns); 254 m_aTable.SelectRow( nRow, sal_True ); 255 } 256 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleChildSelected( sal_Int32 nChildIndex ) 257 { 258 TCSolarGuard aSolarGuard; 259 ::osl::MutexGuard aGuard( getOslMutex() ); 260 ensureIsAlive(); 261 ensureIsValidIndex( nChildIndex ); 262 sal_Int32 nColumns = m_aTable.GetColumnCount(); 263 sal_Int32 nRow = (nChildIndex / nColumns); 264 return isAccessibleRowSelected(nRow); 265 } 266 void SAL_CALL AccessibleGridControlTable::clearAccessibleSelection() 267 { 268 TCSolarGuard aSolarGuard; 269 ::osl::MutexGuard aGuard( getOslMutex() ); 270 ensureIsAlive(); 271 m_aTable.SelectAllRows( false ); 272 } 273 void SAL_CALL AccessibleGridControlTable::selectAllAccessibleChildren() 274 { 275 TCSolarGuard aSolarGuard; 276 ::osl::MutexGuard aGuard( getOslMutex() ); 277 ensureIsAlive(); 278 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); 279 for(int i=0;i<m_aTable.GetRowCount();i++) 280 selectedRows[i]=i; 281 } 282 sal_Int32 SAL_CALL AccessibleGridControlTable::getSelectedAccessibleChildCount() 283 { 284 TCSolarGuard aSolarGuard; 285 ::osl::MutexGuard aGuard( getOslMutex() ); 286 ensureIsAlive(); 287 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); 288 sal_Int32 nColumns = m_aTable.GetColumnCount(); 289 return selectedRows.getLength()*nColumns; 290 } 291 Reference< XAccessible > SAL_CALL 292 AccessibleGridControlTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 293 { 294 TCSolarGuard aSolarGuard; 295 ::osl::MutexGuard aGuard( getOslMutex() ); 296 ensureIsAlive(); 297 if(isAccessibleChildSelected(nSelectedChildIndex)) 298 return getAccessibleChild(nSelectedChildIndex); 299 else 300 return NULL; 301 } 302 //not implemented yet, because only row selection possible 303 void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild( 304 sal_Int32 nSelectedChildIndex ) 305 { 306 TCSolarGuard aSolarGuard; 307 ::osl::MutexGuard aGuard( getOslMutex() ); 308 ensureIsAlive(); 309 (void)nSelectedChildIndex; 310 } 311 // XInterface ----------------------------------------------------------------- 312 313 Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType ) 314 { 315 Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) ); 316 return aAny.hasValue() ? 317 aAny : AccessibleGridControlTableImplHelper1::queryInterface( rType ); 318 } 319 320 void SAL_CALL AccessibleGridControlTable::acquire() throw () 321 { 322 AccessibleGridControlTableBase::acquire(); 323 } 324 325 void SAL_CALL AccessibleGridControlTable::release() throw () 326 { 327 AccessibleGridControlTableBase::release(); 328 } 329 // XServiceInfo --------------------------------------------------------------- 330 331 OUString SAL_CALL AccessibleGridControlTable::getImplementationName() 332 { 333 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTable" ) ); 334 } 335 336 // internal virtual methods --------------------------------------------------- 337 338 Rectangle AccessibleGridControlTable::implGetBoundingBox() 339 { 340 Window* pParent = m_aTable.GetAccessibleParentWindow(); 341 DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" ); 342 Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent )); 343 Rectangle aTableRect( m_aTable.calcTableRect() ); 344 long nX = aGridRect.Left() + aTableRect.Left(); 345 long nY = aGridRect.Top() + aTableRect.Top(); 346 long nWidth = aGridRect.GetSize().Width()-aTableRect.Left(); 347 long nHeight = aGridRect.GetSize().Height()-aTableRect.Top(); 348 Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight )); 349 return aTable; 350 } 351 352 Rectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen() 353 { 354 Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( NULL )); 355 Rectangle aTableRect( m_aTable.calcTableRect() ); 356 long nX = aGridRect.Left() + aTableRect.Left(); 357 long nY = aGridRect.Top() + aTableRect.Top(); 358 long nWidth = aGridRect.GetSize().Width()-aTableRect.Left(); 359 long nHeight = aGridRect.GetSize().Height()-aTableRect.Top(); 360 Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight )); 361 return aTable; 362 } 363 // internal helper methods ---------------------------------------------------- 364 Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar( 365 sal_Int32 nChildIndex ) 366 { 367 Reference< XAccessible > xRet; 368 Reference< XAccessibleContext > xContext( m_xParent, uno::UNO_QUERY ); 369 if( xContext.is() ) 370 { 371 try 372 { 373 xRet = xContext->getAccessibleChild( nChildIndex ); 374 } 375 catch( lang::IndexOutOfBoundsException& ) 376 { 377 DBG_ERROR( "implGetHeaderBar - wrong child index" ); 378 } 379 // RuntimeException goes to caller 380 } 381 return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY ); 382 } 383 384 std::vector< AccessibleGridControlTableCell* >& AccessibleGridControlTable::getCellVector() 385 { 386 return m_pCellVector; 387 } 388 389 std::vector< Reference< XAccessible > >& AccessibleGridControlTable::getAccessibleCellVector() 390 { 391 return m_pAccessCellVector; 392 } 393 // ============================================================================ 394 395 } // namespace accessibility 396 397 // ============================================================================ 398