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_svx.hxx" 26 27 #include <com/sun/star/table/XMergeableCell.hpp> 28 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 29 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 30 31 #include <comphelper/accessiblewrapper.hxx> 32 #include <vos/mutex.hxx> 33 #include <tools/debug.hxx> 34 #include <vcl/svapp.hxx> 35 36 #include <svx/AccessibleTableShape.hxx> 37 #include <svx/sdr/table/tablecontroller.hxx> 38 #include "accessiblecell.hxx" 39 40 #include <algorithm> 41 42 #include <cppuhelper/implbase1.hxx> 43 #include <svx/svdotable.hxx> 44 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 45 #include <com/sun/star/view/XSelectionSupplier.hpp> 46 47 using ::rtl::OUString; 48 49 using namespace ::accessibility; 50 using namespace ::sdr::table; 51 using namespace ::com::sun::star::accessibility; 52 using namespace ::com::sun::star::uno; 53 using namespace ::com::sun::star::beans; 54 using namespace ::com::sun::star::util; 55 using namespace ::com::sun::star::lang; 56 using namespace ::com::sun::star::drawing; 57 using namespace ::com::sun::star::table; 58 using namespace ::com::sun::star::container; 59 60 #define C2U(x) OUString(RTL_CONSTASCII_USTRINGPARAM(x)) 61 62 namespace accessibility 63 { 64 65 struct hash 66 { 67 std::size_t operator()( const Reference< XCell >& xCell ) const 68 { 69 return std::size_t( xCell.get() ); 70 } 71 }; 72 73 typedef std::hash_map< Reference< XCell >, rtl::Reference< AccessibleCell >, hash > AccessibleCellMap; 74 75 //----------------------------------------------------------------------------- 76 // AccessibleTableShapeImpl 77 //----------------------------------------------------------------------------- 78 79 class AccessibleTableShapeImpl : public cppu::WeakImplHelper1< XModifyListener > 80 { 81 public: 82 AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo ); 83 84 void init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable ); 85 void dispose(); 86 87 Reference< XAccessible > getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException); 88 void getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException ); 89 90 // XModifyListener 91 virtual void SAL_CALL modified( const EventObject& aEvent ) throw (RuntimeException); 92 93 // XEventListener 94 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); 95 96 AccessibleShapeTreeInfo& mrShapeTreeInfo; 97 Reference< XTable > mxTable; 98 AccessibleCellMap maChildMap; 99 Reference< XAccessible> mxAccessible; 100 sal_Int32 mRowCount, mColCount; 101 //get the cached AccessibleCell from XCell 102 Reference< AccessibleCell > getAccessibleCell (Reference< XCell > xCell); 103 }; 104 105 //----------------------------------------------------------------------------- 106 107 AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo ) 108 : mrShapeTreeInfo( rShapeTreeInfo ) 109 , mRowCount(0) 110 , mColCount(0) 111 { 112 } 113 114 //----------------------------------------------------------------------------- 115 116 void AccessibleTableShapeImpl::init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable ) 117 { 118 mxAccessible = xAccessible; 119 mxTable = xTable; 120 121 if( mxTable.is() ) 122 { 123 Reference< XModifyListener > xListener( this ); 124 mxTable->addModifyListener( xListener ); 125 //register the listener with table model 126 Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(xTable, UNO_QUERY); 127 Reference< ::com::sun::star::view::XSelectionChangeListener > xSelListener( xAccessible, UNO_QUERY ); 128 if (xSelSupplier.is()) 129 xSelSupplier->addSelectionChangeListener(xSelListener); 130 mRowCount = mxTable->getRowCount(); 131 mColCount = mxTable->getColumnCount(); 132 } 133 } 134 135 //----------------------------------------------------------------------------- 136 137 void AccessibleTableShapeImpl::dispose() 138 { 139 if( mxTable.is() ) 140 { 141 //IAccessibility2 Implementation 2009-----, remove all the cell's acc object in table's dispose. 142 for( AccessibleCellMap::iterator iter( maChildMap.begin() ); iter != maChildMap.end(); iter++ ) 143 { 144 (*iter).second->dispose(); 145 } 146 Reference< XModifyListener > xListener( this ); 147 mxTable->removeModifyListener( xListener ); 148 mxTable.clear(); 149 } 150 mxAccessible.clear(); 151 } 152 153 //----------------------------------------------------------------------------- 154 //IAccessibility2 Implementation 2009-----, get the cached AccessibleCell from XCell 155 Reference< AccessibleCell > AccessibleTableShapeImpl::getAccessibleCell (Reference< XCell > xCell) 156 { 157 AccessibleCellMap::iterator iter( maChildMap.find( xCell ) ); 158 159 if( iter != maChildMap.end() ) 160 { 161 Reference< AccessibleCell > xChild( (*iter).second.get() ); 162 return xChild; 163 } 164 return Reference< AccessibleCell >(); 165 } 166 167 //----------------------------------------------------------------------------- 168 Reference< XAccessible > AccessibleTableShapeImpl::getAccessibleChild( sal_Int32 nChildIndex ) throw(IndexOutOfBoundsException) 169 { 170 sal_Int32 nColumn = 0, nRow = 0; 171 getColumnAndRow( nChildIndex, nColumn, nRow ); 172 173 Reference< XCell > xCell( mxTable->getCellByPosition( nColumn, nRow ) ); 174 AccessibleCellMap::iterator iter( maChildMap.find( xCell ) ); 175 176 if( iter != maChildMap.end() ) 177 { 178 Reference< XAccessible > xChild( (*iter).second.get() ); 179 return xChild; 180 } 181 else 182 { 183 CellRef xCellRef( dynamic_cast< Cell* >( xCell.get() ) ); 184 185 rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCellRef, nChildIndex, mrShapeTreeInfo ) ); 186 187 xAccessibleCell->Init(); 188 maChildMap[xCell] = xAccessibleCell; 189 190 xAccessibleCell->Init(); 191 192 Reference< XAccessible > xChild( xAccessibleCell.get() ); 193 return xChild; 194 } 195 } 196 197 //----------------------------------------------------------------------------- 198 199 void AccessibleTableShapeImpl::getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException ) 200 { 201 rnRow = 0; 202 rnColumn = nChildIndex; 203 204 if( mxTable.is() ) 205 { 206 const sal_Int32 nColumnCount = mxTable->getColumnCount(); 207 while( rnColumn >= nColumnCount ) 208 { 209 rnRow++; 210 rnColumn -= nColumnCount; 211 } 212 213 if( rnRow < mxTable->getRowCount() ) 214 return; 215 } 216 217 throw IndexOutOfBoundsException(); 218 } 219 220 // XModifyListener 221 void SAL_CALL AccessibleTableShapeImpl::modified( const EventObject& /*aEvent*/ ) throw (RuntimeException) 222 { 223 if( mxTable.is() ) try 224 { 225 // structural changes may have happened to the table, validate all accessible cell instances 226 AccessibleCellMap aTempChildMap; 227 aTempChildMap.swap( maChildMap ); 228 229 // first move all still existing cells to maChildMap again and update their index 230 231 const sal_Int32 nRowCount = mxTable->getRowCount(); 232 const sal_Int32 nColCount = mxTable->getColumnCount(); 233 234 sal_Bool bRowOrColumnChanged = sal_False; 235 if (mRowCount != nRowCount || mColCount != nColCount ) 236 { 237 bRowOrColumnChanged = sal_True; 238 mRowCount = nRowCount; 239 mColCount = nColCount; 240 } 241 sal_Int32 nChildIndex = 0; 242 243 for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) 244 { 245 for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 246 { 247 Reference< XCell > xCell( mxTable->getCellByPosition( nCol, nRow ) ); 248 AccessibleCellMap::iterator iter( aTempChildMap.find( xCell ) ); 249 250 if( iter != aTempChildMap.end() ) 251 { 252 rtl::Reference< AccessibleCell > xAccessibleCell( (*iter).second ); 253 xAccessibleCell->setIndexInParent( nChildIndex ); 254 //IAccessibility2 Implementation 2009-----, the children may need to updated 255 //xAccessibleCell->CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any()); 256 xAccessibleCell->UpdateChildren(); 257 // If row or column count is changed, there is split or merge, so all cell's acc name should be updated 258 if (bRowOrColumnChanged) 259 { 260 xAccessibleCell->SetAccessibleName(xAccessibleCell->getAccessibleName(), AccessibleContextBase::ManuallySet); 261 } 262 // For merged cell, add invisible & disabled state. 263 Reference< XMergeableCell > xMergedCell( mxTable->getCellByPosition( nCol, nRow ), UNO_QUERY ); 264 if (xMergedCell.is() && xMergedCell->isMerged()) 265 { 266 xAccessibleCell->ResetState(AccessibleStateType::VISIBLE); 267 xAccessibleCell->ResetState(AccessibleStateType::ENABLED); 268 // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent 269 // xAccessibleCell->SetState(AccessibleStateType::OFFSCREEN); 270 xAccessibleCell->ResetState(AccessibleStateType::SHOWING); 271 } 272 else 273 { 274 xAccessibleCell->SetState(AccessibleStateType::VISIBLE); 275 xAccessibleCell->SetState(AccessibleStateType::ENABLED); 276 // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent 277 // xAccessibleCell->ResetState(AccessibleStateType::OFFSCREEN); 278 xAccessibleCell->SetState(AccessibleStateType::SHOWING); 279 } 280 281 // move still existing cell from temporary child map to our child map 282 maChildMap[xCell] = xAccessibleCell; 283 aTempChildMap.erase( iter ); 284 } 285 //IAccessibility2 Implementation 2009-----, need to add the new added cell on demand 286 else 287 { 288 CellRef xCellRef( dynamic_cast< Cell* >( xCell.get() ) ); 289 290 rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCellRef, nChildIndex, mrShapeTreeInfo ) ); 291 292 xAccessibleCell->Init(); 293 maChildMap[xCell] = xAccessibleCell; 294 } 295 296 ++nChildIndex; 297 } 298 } 299 300 // all accessible cell instances still left in aTempChildMap must be disposed 301 // as they are no longer part of the table 302 303 for( AccessibleCellMap::iterator iter( aTempChildMap.begin() ); iter != aTempChildMap.end(); iter++ ) 304 { 305 (*iter).second->dispose(); 306 } 307 //IAccessibility2 Implementation 2009-----, notify bridge to update the acc cache. 308 AccessibleTableShape *pAccTable = dynamic_cast <AccessibleTableShape *> (mxAccessible.get()); 309 pAccTable->CommitChange(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); 310 } 311 catch( Exception& ) 312 { 313 DBG_ERROR("svx::AccessibleTableShape::modified(), exception caught!"); 314 } 315 } 316 317 // XEventListener 318 void SAL_CALL AccessibleTableShapeImpl::disposing( const EventObject& /*Source*/ ) throw (RuntimeException) 319 { 320 } 321 322 //----------------------------------------------------------------------------- 323 // AccessibleTableShape 324 //----------------------------------------------------------------------------- 325 326 //----------------------------------------------------------------------------- 327 328 AccessibleTableShape::AccessibleTableShape( const AccessibleShapeInfo& rShapeInfo, const AccessibleShapeTreeInfo& rShapeTreeInfo) 329 : AccessibleTableShape_Base(rShapeInfo, rShapeTreeInfo) 330 , mxImpl( new AccessibleTableShapeImpl( maShapeTreeInfo ) ) 331 { 332 } 333 334 //----------------------------------------------------------------------------- 335 336 AccessibleTableShape::~AccessibleTableShape (void) 337 { 338 } 339 340 //----------------------------------------------------------------------------- 341 342 void AccessibleTableShape::Init() 343 { 344 try 345 { 346 mnPreviousSelectionCount = 0; 347 Reference< XPropertySet > xSet( mxShape, UNO_QUERY_THROW ); 348 Reference< XTable > xTable( xSet->getPropertyValue(C2U("Model")), UNO_QUERY_THROW ); 349 350 mxImpl->init( this, xTable ); 351 } 352 catch( Exception& ) 353 { 354 DBG_ERROR("AccessibleTableShape::init(), exception caught?"); 355 } 356 357 AccessibleTableShape_Base::Init(); 358 } 359 360 //----------------------------------------------------------------------------- 361 362 SvxTableController* AccessibleTableShape::getTableController() 363 { 364 SdrView* pView = maShapeTreeInfo.GetSdrView (); 365 if( pView ) 366 return dynamic_cast< SvxTableController* >( pView->getSelectionController().get() ); 367 else 368 return 0; 369 } 370 371 //----------------------------------------------------------------------------- 372 // XInterface 373 //----------------------------------------------------------------------------- 374 375 Any SAL_CALL AccessibleTableShape::queryInterface( const Type& aType ) throw (RuntimeException) 376 { 377 if ( aType == ::getCppuType((Reference<XAccessibleTableSelection> *)0) ) 378 { 379 Reference<XAccessibleTableSelection> xThis( this ); 380 Any aRet; 381 aRet <<= xThis; 382 return aRet; 383 } 384 else 385 return AccessibleTableShape_Base::queryInterface( aType ); 386 } 387 388 //----------------------------------------------------------------------------- 389 390 void SAL_CALL AccessibleTableShape::acquire( ) throw () 391 { 392 AccessibleTableShape_Base::acquire(); 393 } 394 395 //----------------------------------------------------------------------------- 396 397 void SAL_CALL AccessibleTableShape::release( ) throw () 398 { 399 AccessibleTableShape_Base::release(); 400 } 401 402 //----------------------------------------------------------------------------- 403 // XAccessible 404 //----------------------------------------------------------------------------- 405 406 Reference< XAccessibleContext > SAL_CALL AccessibleTableShape::getAccessibleContext(void) throw (RuntimeException) 407 { 408 return AccessibleShape::getAccessibleContext (); 409 } 410 411 //----------------------------------------------------------------------------- 412 OUString SAL_CALL AccessibleTableShape::getImplementationName(void) throw (RuntimeException) 413 { 414 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.accessibility.AccessibleTableShape" ) ); 415 } 416 417 //----------------------------------------------------------------------------- 418 419 OUString AccessibleTableShape::CreateAccessibleBaseName(void) throw (RuntimeException) 420 { 421 return OUString (RTL_CONSTASCII_USTRINGPARAM("TableShape")); 422 } 423 424 //-------------------------------------------------------------------- 425 426 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleChildCount( ) throw(RuntimeException) 427 { 428 ::vos::OGuard aSolarGuard(::Application::GetSolarMutex()); 429 return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() * mxImpl->mxTable->getColumnCount() : 0; 430 } 431 432 //-------------------------------------------------------------------- 433 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException) 434 { 435 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 436 ThrowIfDisposed(); 437 438 return mxImpl->getAccessibleChild( i ); 439 } 440 441 //-------------------------------------------------------------------- 442 Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableShape::getAccessibleRelationSet( ) throw (RuntimeException) 443 { 444 return AccessibleShape::getAccessibleRelationSet( ); 445 } 446 447 //-------------------------------------------------------------------- 448 449 sal_Int16 SAL_CALL AccessibleTableShape::getAccessibleRole (void) throw (RuntimeException) 450 { 451 return AccessibleRole::TABLE; 452 } 453 454 //-------------------------------------------------------------------- 455 456 void SAL_CALL AccessibleTableShape::disposing (void) 457 { 458 mxImpl->dispose(); 459 460 // let the base do it's stuff 461 AccessibleShape::disposing(); 462 } 463 464 //-------------------------------------------------------------------- 465 // XAccessibleTable 466 //-------------------------------------------------------------------- 467 468 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowCount() throw (RuntimeException) 469 { 470 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 471 return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() : 0; 472 } 473 474 //-------------------------------------------------------------------- 475 476 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnCount( ) throw (RuntimeException) 477 { 478 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 479 return mxImpl->mxTable.is() ? mxImpl->mxTable->getColumnCount() : 0; 480 } 481 482 //-------------------------------------------------------------------- 483 484 OUString SAL_CALL AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException) 485 { 486 checkCellPosition( 0, nRow ); 487 return OUString(); 488 } 489 490 //-------------------------------------------------------------------- 491 492 OUString SAL_CALL AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 493 { 494 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 495 checkCellPosition( nColumn, 0 ); 496 return OUString(); 497 } 498 499 //-------------------------------------------------------------------- 500 501 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 502 { 503 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 504 checkCellPosition( nColumn, nRow ); 505 if( mxImpl->mxTable.is() ) 506 { 507 Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY ); 508 if( xCell.is() ) 509 return xCell->getRowSpan(); 510 } 511 return 1; 512 } 513 514 //-------------------------------------------------------------------- 515 516 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 517 { 518 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 519 checkCellPosition( nColumn, nRow ); 520 if( mxImpl->mxTable.is() ) 521 { 522 Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY ); 523 if( xCell.is() ) 524 return xCell->getColumnSpan(); 525 } 526 return 1; 527 } 528 529 //-------------------------------------------------------------------- 530 531 Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleRowHeaders( ) throw (RuntimeException) 532 { 533 //Reference< XAccessibleTable > xRet( this ); // todo 534 Reference< XAccessibleTable > xRet; 535 SvxTableController* pController = getTableController(); 536 if( pController ) 537 { 538 if( pController->isRowHeader() ) 539 { 540 AccessibleTableHeaderShape* pTableHeader = new AccessibleTableHeaderShape( this, sal_True ); 541 xRet.set( pTableHeader ); 542 } 543 } 544 return xRet; 545 } 546 547 //-------------------------------------------------------------------- 548 549 Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleColumnHeaders( ) throw (RuntimeException) 550 { 551 //Reference< XAccessibleTable > xRet( this ); // todo 552 Reference< XAccessibleTable > xRet; 553 SvxTableController* pController = getTableController(); 554 if( pController ) 555 { 556 if( pController->isColumnHeader() ) 557 { 558 AccessibleTableHeaderShape* pTableHeader = new AccessibleTableHeaderShape( this, sal_False ); 559 xRet.set( pTableHeader ); 560 } 561 } 562 return xRet; 563 } 564 565 //-------------------------------------------------------------------- 566 567 Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleRows( ) throw (RuntimeException) 568 { 569 /*Sequence< sal_Int32 > aRet;*/ 570 sal_Int32 nRow = getAccessibleRowCount(); 571 ::std::vector< sal_Bool > aSelected( nRow, sal_True ); 572 sal_Int32 nCount = nRow; 573 for( sal_Int32 i = 0; i < nRow; i++ ) 574 { 575 try 576 { 577 aSelected[i] = isAccessibleRowSelected( i ); 578 } 579 catch( ... ) 580 { 581 return Sequence< sal_Int32 >(); 582 } 583 584 if( !aSelected[i] ) 585 nCount--; 586 } 587 Sequence < sal_Int32 > aRet( nCount ); 588 sal_Int32 *pRet = aRet.getArray(); 589 sal_Int32 nPos = 0; 590 size_t nSize = aSelected.size(); 591 for( size_t i=0; i < nSize && nPos < nCount; i++ ) 592 { 593 if( aSelected[i] ) 594 { 595 *pRet++ = i; 596 nPos++; 597 } 598 } 599 600 return aRet; 601 } 602 603 //-------------------------------------------------------------------- 604 605 Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleColumns( ) throw (RuntimeException) 606 { 607 /*Sequence< sal_Int32 > aRet;*/ 608 sal_Int32 nColumn = getAccessibleColumnCount(); 609 ::std::vector< sal_Bool > aSelected( nColumn, sal_True ); 610 sal_Int32 nCount = nColumn; 611 for( sal_Int32 i = 0; i < nColumn; i++ ) 612 { 613 try 614 { 615 aSelected[i] = isAccessibleColumnSelected( i ); 616 } 617 catch( ... ) 618 { 619 return Sequence< sal_Int32 >(); 620 } 621 622 if( !aSelected[i] ) 623 nCount--; 624 } 625 Sequence < sal_Int32 > aRet( nCount ); 626 sal_Int32 *pRet = aRet.getArray(); 627 sal_Int32 nPos = 0; 628 size_t nSize = aSelected.size(); 629 for( size_t i=0; i < nSize && nPos < nCount; i++ ) 630 { 631 if( aSelected[i] ) 632 { 633 *pRet++ = i; 634 nPos++; 635 } 636 } 637 638 return aRet; 639 } 640 641 //-------------------------------------------------------------------- 642 643 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException) 644 { 645 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 646 checkCellPosition( 0, nRow ); 647 SvxTableController* pController = getTableController(); 648 if( pController ) 649 { 650 return pController->isRowSelected( nRow ); 651 } 652 return sal_False; 653 } 654 655 //-------------------------------------------------------------------- 656 657 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 658 { 659 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 660 checkCellPosition( nColumn, 0 ); 661 SvxTableController* pController = getTableController(); 662 if( pController ) 663 { 664 return pController->isColumnSelected( nColumn ); 665 } 666 return sal_False; 667 } 668 669 //-------------------------------------------------------------------- 670 671 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 672 { 673 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 674 checkCellPosition( nColumn, nRow ); 675 676 sal_Int32 nChildIndex = 0; 677 if( mxImpl->mxTable.is() ) 678 nChildIndex = mxImpl->mxTable->getColumnCount() * nRow + nColumn; 679 680 return getAccessibleChild( nChildIndex ); 681 } 682 683 //-------------------------------------------------------------------- 684 685 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCaption( ) throw (RuntimeException) 686 { 687 Reference< XAccessible > xRet; 688 return xRet; 689 } 690 691 //-------------------------------------------------------------------- 692 693 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleSummary( ) throw (RuntimeException) 694 { 695 Reference< XAccessible > xRet; 696 return xRet; 697 } 698 699 //-------------------------------------------------------------------- 700 701 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 702 { 703 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 704 checkCellPosition( nColumn, nRow ); 705 706 SvxTableController* pController = getTableController(); 707 if( pController && pController->hasSelectedCells() ) 708 { 709 CellPos aFirstPos, aLastPos; 710 pController->getSelectedCells( aFirstPos, aLastPos ); 711 if( (aFirstPos.mnRow <= nRow) && (aFirstPos.mnCol <= nColumn) && (nRow <= aLastPos.mnRow) && (nColumn <= aLastPos.mnCol) ) 712 return sal_True; 713 } 714 715 return sal_False; 716 } 717 718 //-------------------------------------------------------------------- 719 720 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 721 { 722 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 723 checkCellPosition( nColumn, nRow ); 724 return mxImpl->mxTable.is() ? (nRow * mxImpl->mxTable->getColumnCount() + nColumn) : 0; 725 } 726 727 //-------------------------------------------------------------------- 728 729 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRow( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 730 { 731 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 732 sal_Int32 nColumn = 0, nRow = 0; 733 mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow ); 734 return nRow; 735 } 736 737 //-------------------------------------------------------------------- 738 739 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumn( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 740 { 741 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 742 sal_Int32 nColumn = 0, nRow = 0; 743 mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow ); 744 //return nChildIndex; 745 return nColumn; 746 } 747 748 //-------------------------------------------------------------------- 749 // XAccessibleSelection 750 //-------------------------------------------------------------------- 751 752 void SAL_CALL AccessibleTableShape::selectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException ) 753 { 754 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 755 CellPos aPos; 756 mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow ); 757 758 // todo, select table shape?!? 759 SvxTableController* pController = getTableController(); 760 if( pController ) 761 { 762 CellPos aFirstPos( aPos ), aLastPos( aPos ); 763 if( pController->hasSelectedCells() ) 764 { 765 pController->getSelectedCells( aFirstPos, aLastPos ); 766 767 aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow ); 768 aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol ); 769 aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow ); 770 aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol ); 771 } 772 pController->setSelectedCells( aFirstPos, aLastPos ); 773 } 774 } 775 776 //-------------------------------------------------------------------- 777 778 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException ) 779 { 780 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 781 CellPos aPos; 782 mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow ); 783 784 // Para order is not correct 785 //return isAccessibleSelected(aPos.mnCol, aPos.mnRow); 786 return isAccessibleSelected(aPos.mnRow, aPos.mnCol); 787 } 788 789 //-------------------------------------------------------------------- 790 791 void SAL_CALL AccessibleTableShape::clearAccessibleSelection() throw ( RuntimeException ) 792 { 793 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 794 795 SvxTableController* pController = getTableController(); 796 if( pController ) 797 pController->clearSelection(); 798 } 799 //-------------------------------------------------------------------- 800 801 void SAL_CALL AccessibleTableShape::selectAllAccessibleChildren() throw ( RuntimeException ) 802 { 803 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 804 805 // todo: force selection of shape? 806 SvxTableController* pController = getTableController(); 807 if( pController ) 808 pController->selectAll(); 809 } 810 811 //-------------------------------------------------------------------- 812 813 sal_Int32 SAL_CALL AccessibleTableShape::getSelectedAccessibleChildCount() throw ( RuntimeException ) 814 { 815 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 816 817 SvxTableController* pController = getTableController(); 818 if( pController && pController->hasSelectedCells() ) 819 { 820 CellPos aFirstPos, aLastPos; 821 pController->getSelectedCells( aFirstPos, aLastPos ); 822 823 const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1; 824 const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1; 825 return nSelectedRows * nSelectedColumns; 826 } 827 828 return 0; 829 } 830 831 //-------------------------------------------------------------------- 832 833 Reference< XAccessible > SAL_CALL AccessibleTableShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException) 834 { 835 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 836 837 /*SvxTableController* pController = getTableController(); 838 if( pController && pController->hasSelectedCells() ) 839 { 840 CellPos aFirstPos, aLastPos; 841 pController->getSelectedCells( aFirstPos, aLastPos ); 842 843 const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1; 844 const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1; 845 846 if( nSelectedChildIndex < (nSelectedRows * nSelectedColumns) ) 847 { 848 while( nSelectedChildIndex >= nSelectedColumns ) 849 { 850 aFirstPos.mnRow++; 851 nSelectedChildIndex -= nSelectedColumns; 852 } 853 return getAccessibleCellAt( nSelectedColumns, aFirstPos.mnRow ); 854 } 855 } 856 857 throw IndexOutOfBoundsException(); 858 */ 859 if( nSelectedChildIndex < 0 ) 860 throw IndexOutOfBoundsException(); 861 862 sal_Int32 nChildIndex = GetIndexOfSelectedChild( nSelectedChildIndex ); 863 864 if( nChildIndex < 0 ) 865 throw IndexOutOfBoundsException(); 866 867 if ( nChildIndex >= getAccessibleChildCount() ) 868 { 869 throw IndexOutOfBoundsException(); 870 } 871 872 return getAccessibleChild( nChildIndex ); 873 } 874 875 //-------------------------------------------------------------------- 876 877 void SAL_CALL AccessibleTableShape::deselectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException ) 878 { 879 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 880 CellPos aPos; 881 mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow ); 882 883 // todo, select table shape?!? 884 SvxTableController* pController = getTableController(); 885 if( pController && pController->hasSelectedCells() ) 886 { 887 CellPos aFirstPos, aLastPos; 888 pController->getSelectedCells( aFirstPos, aLastPos ); 889 890 // create a selection where aPos is not part of anymore 891 aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow+1 ); 892 aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol+1 ); 893 aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow-1 ); 894 aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol-1 ); 895 896 // new selection may be invalid (child to deselect is not at a border of the selection but in between) 897 if( (aFirstPos.mnRow > aLastPos.mnRow) || (aFirstPos.mnCol > aLastPos.mnCol) ) 898 pController->clearSelection(); // if selection is invalid, clear all 899 else 900 pController->setSelectedCells( aFirstPos, aLastPos ); 901 } 902 } 903 //-------------------------------------------------------------------- 904 905 //===== XAccessibleTableSelection ============================================ 906 sal_Bool SAL_CALL AccessibleTableShape::selectRow( sal_Int32 row ) 907 throw (IndexOutOfBoundsException, RuntimeException) 908 { 909 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 910 SvxTableController* pController = getTableController(); 911 if( !pController ) 912 return sal_False; 913 return pController->selectRow( row ); 914 } 915 sal_Bool SAL_CALL AccessibleTableShape::selectColumn( sal_Int32 column ) 916 throw (IndexOutOfBoundsException, RuntimeException) 917 { 918 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 919 SvxTableController* pController = getTableController(); 920 if( !pController ) 921 return sal_False; 922 return pController->selectColumn( column ); 923 } 924 sal_Bool SAL_CALL AccessibleTableShape::unselectRow( sal_Int32 row ) 925 throw (IndexOutOfBoundsException, RuntimeException) 926 { 927 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 928 SvxTableController* pController = getTableController(); 929 if( !pController ) 930 return sal_False; 931 return pController->deselectRow( row ); 932 } 933 sal_Bool SAL_CALL AccessibleTableShape::unselectColumn( sal_Int32 column ) 934 throw (IndexOutOfBoundsException, RuntimeException) 935 { 936 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 937 SvxTableController* pController = getTableController(); 938 if( !pController ) 939 return sal_False; 940 return pController->deselectColumn( column ); 941 } 942 sal_Int32 AccessibleTableShape::GetIndexOfSelectedChild( 943 sal_Int32 nSelectedChildIndex ) const 944 { 945 sal_Int32 nChildren = const_cast<AccessibleTableShape*>(this)->getAccessibleChildCount(); 946 947 if( nSelectedChildIndex >= nChildren ) 948 return -1L; 949 950 sal_Int32 n = 0; 951 while( n < nChildren ) 952 { 953 if( const_cast<AccessibleTableShape*>(this)->isAccessibleChildSelected( n ) ) 954 { 955 if( 0 == nSelectedChildIndex ) 956 break; 957 else 958 --nSelectedChildIndex; 959 } 960 ++n; 961 } 962 963 return n < nChildren ? n : -1L; 964 } 965 void AccessibleTableShape::getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException ) 966 { 967 mxImpl->getColumnAndRow(nChildIndex, rnColumn, rnRow); 968 } 969 //-------------------------------------------------------------------- 970 // XSelectionChangeListener 971 void SAL_CALL 972 AccessibleTableShape::disposing (const EventObject& aEvent) 973 throw (RuntimeException) 974 { 975 AccessibleShape::disposing(aEvent); 976 } 977 void SAL_CALL AccessibleTableShape::selectionChanged (const EventObject& rEvent) 978 throw (RuntimeException) 979 { 980 //::sdr::table::CellRef xCellRef = static_cast< ::sdr::table::CellRef > (rEvent.Source); 981 Reference< XCell > xCell(rEvent.Source, UNO_QUERY); 982 if (xCell.is()) 983 { 984 Reference< AccessibleCell > xAccCell = mxImpl->getAccessibleCell( xCell ); 985 if (xAccCell.is()) 986 { 987 sal_Int32 nIndex = xAccCell->getAccessibleIndexInParent(), 988 nCount = getSelectedAccessibleChildCount(); 989 sal_Bool bSelected = isAccessibleChildSelected(nIndex); 990 if (mnPreviousSelectionCount == 0 && nCount > 0 && bSelected) 991 { 992 xAccCell->SetState(AccessibleStateType::SELECTED); 993 xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED, Any(), Any()); 994 } 995 else if (bSelected) 996 { 997 xAccCell->SetState(AccessibleStateType::SELECTED); 998 xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED_ADD, Any(), Any()); 999 } 1000 else 1001 { 1002 xAccCell->ResetState(AccessibleStateType::SELECTED); 1003 xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, Any(), Any()); 1004 } 1005 mnPreviousSelectionCount = nCount; 1006 } 1007 } 1008 } 1009 // Get the currently active cell which is text editing 1010 AccessibleCell* AccessibleTableShape::GetActiveAccessibleCell() 1011 { 1012 sal_Bool bCellEditing = sal_False; 1013 Reference< AccessibleCell > xAccCell; 1014 AccessibleCell* pAccCell = NULL; 1015 SvxTableController* pController = getTableController(); 1016 if (pController) 1017 { 1018 ::sdr::table::SdrTableObj* pTableObj = pController->GetTableObj(); 1019 if ( pTableObj ) 1020 { 1021 ::sdr::table::CellRef xCellRef (pTableObj->getActiveCell()); 1022 if ( xCellRef.is() ) 1023 { 1024 bCellEditing = xCellRef->IsTextEditActive(); 1025 if (bCellEditing) 1026 { 1027 //Reference< XCell > xCell(xCellRef.get(), UNO_QUERY); 1028 xAccCell = mxImpl->getAccessibleCell(Reference< XCell >( xCellRef.get() )); 1029 if (xAccCell.is()) 1030 pAccCell = xAccCell.get(); 1031 } 1032 } 1033 } 1034 } 1035 return pAccCell; 1036 } 1037 //-------------------------------------------------------------------- 1038 //If current active cell is in editing, the focus state should be set to internal text 1039 sal_Bool AccessibleTableShape::SetState (sal_Int16 aState) 1040 { 1041 AccessibleCell* pActiveAccessibleCell = GetActiveAccessibleCell(); 1042 sal_Bool bStateHasChanged = sal_False; 1043 if (aState == AccessibleStateType::FOCUSED && pActiveAccessibleCell != NULL) 1044 { 1045 return pActiveAccessibleCell->SetState(aState); 1046 } 1047 else 1048 bStateHasChanged = AccessibleShape::SetState (aState); 1049 return bStateHasChanged; 1050 } 1051 //-------------------------------------------------------------------- 1052 //If current active cell is in editing, the focus state should be reset to internal text 1053 sal_Bool AccessibleTableShape::ResetState (sal_Int16 aState) 1054 { 1055 AccessibleCell* pActiveAccessibleCell = GetActiveAccessibleCell(); 1056 sal_Bool bStateHasChanged = sal_False; 1057 if (aState == AccessibleStateType::FOCUSED && pActiveAccessibleCell != NULL) 1058 { 1059 return pActiveAccessibleCell->ResetState(aState); 1060 } 1061 else 1062 bStateHasChanged = AccessibleShape::ResetState (aState); 1063 return bStateHasChanged; 1064 } 1065 //-------------------------------------------------------------------- 1066 sal_Bool AccessibleTableShape::SetStateDirectly (sal_Int16 aState) 1067 { 1068 return AccessibleContextBase::SetState (aState); 1069 } 1070 //-------------------------------------------------------------------- 1071 sal_Bool AccessibleTableShape::ResetStateDirectly (sal_Int16 aState) 1072 { 1073 return AccessibleContextBase::ResetState (aState); 1074 } 1075 void AccessibleTableShape::checkCellPosition( sal_Int32 nCol, sal_Int32 nRow ) throw ( IndexOutOfBoundsException ) 1076 { 1077 if( (nCol >= 0) && (nRow >= 0) && mxImpl->mxTable.is() && (nCol < mxImpl->mxTable->getColumnCount()) && (nRow < mxImpl->mxTable->getRowCount()) ) 1078 return; 1079 1080 throw IndexOutOfBoundsException(); 1081 } 1082 1083 AccessibleTableHeaderShape::AccessibleTableHeaderShape( AccessibleTableShape* pTable, sal_Bool bRow ) 1084 { 1085 mpTable = pTable; 1086 mbRow = bRow; 1087 } 1088 1089 AccessibleTableHeaderShape::~AccessibleTableHeaderShape (void) 1090 { 1091 mpTable = NULL; 1092 } 1093 1094 // XAccessible 1095 Reference< XAccessibleContext > SAL_CALL AccessibleTableHeaderShape::getAccessibleContext(void) throw (RuntimeException) 1096 { 1097 return this; 1098 } 1099 1100 // XAccessibleContext 1101 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleChildCount( ) throw(RuntimeException) 1102 { 1103 return getAccessibleRowCount() * getAccessibleColumnCount(); 1104 } 1105 1106 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException) 1107 { 1108 return mpTable->getAccessibleChild( i ); 1109 } 1110 1111 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleParent (void) throw (RuntimeException) 1112 { 1113 Reference< XAccessible > XParent; 1114 return XParent; 1115 } 1116 1117 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleIndexInParent (void) throw (RuntimeException) 1118 { 1119 return -1; 1120 } 1121 1122 sal_Int16 SAL_CALL AccessibleTableHeaderShape::getAccessibleRole (void) throw (RuntimeException) 1123 { 1124 return mpTable->getAccessibleRole(); 1125 } 1126 1127 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleDescription (void) throw (RuntimeException) 1128 { 1129 return mpTable->getAccessibleDescription(); 1130 } 1131 1132 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleName (void) throw (RuntimeException) 1133 { 1134 return mpTable->getAccessibleName(); 1135 } 1136 1137 Reference< XAccessibleStateSet > SAL_CALL AccessibleTableHeaderShape::getAccessibleStateSet (void) throw (RuntimeException) 1138 { 1139 return mpTable->getAccessibleStateSet(); 1140 } 1141 1142 Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableHeaderShape::getAccessibleRelationSet (void) throw (RuntimeException) 1143 { 1144 return mpTable->getAccessibleRelationSet(); 1145 } 1146 1147 Locale SAL_CALL AccessibleTableHeaderShape::getLocale (void) throw (IllegalAccessibleComponentStateException, RuntimeException) 1148 { 1149 return mpTable->getLocale(); 1150 } 1151 1152 //XAccessibleComponent 1153 sal_Bool SAL_CALL AccessibleTableHeaderShape::containsPoint ( const ::com::sun::star::awt::Point& aPoint ) throw (RuntimeException) 1154 { 1155 return mpTable->containsPoint( aPoint ); 1156 } 1157 1158 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleAtPoint ( const ::com::sun::star::awt::Point& aPoint) throw (RuntimeException) 1159 { 1160 return mpTable->getAccessibleAtPoint( aPoint ); 1161 } 1162 1163 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleTableHeaderShape::getBounds (void) throw (RuntimeException) 1164 { 1165 return mpTable->getBounds(); 1166 } 1167 1168 ::com::sun::star::awt::Point SAL_CALL AccessibleTableHeaderShape::getLocation (void) throw (RuntimeException) 1169 { 1170 return mpTable->getLocation(); 1171 } 1172 1173 ::com::sun::star::awt::Point SAL_CALL AccessibleTableHeaderShape::getLocationOnScreen (void) throw (RuntimeException) 1174 { 1175 return mpTable->getLocationOnScreen(); 1176 } 1177 1178 ::com::sun::star::awt::Size SAL_CALL AccessibleTableHeaderShape::getSize (void) throw (RuntimeException) 1179 { 1180 return mpTable->getSize(); 1181 } 1182 1183 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getForeground (void) throw (RuntimeException) 1184 { 1185 return mpTable->getForeground(); 1186 } 1187 1188 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getBackground (void) throw (RuntimeException) 1189 { 1190 return mpTable->getBackground(); 1191 } 1192 1193 void SAL_CALL AccessibleTableHeaderShape::grabFocus (void) throw (RuntimeException) 1194 { 1195 mpTable->grabFocus(); 1196 } 1197 //===== XAccessibleTable ============================================ 1198 1199 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRowCount() throw (RuntimeException) 1200 { 1201 return mbRow ? 1 : mpTable->getAccessibleRowCount(); 1202 } 1203 1204 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnCount() throw (RuntimeException) 1205 { 1206 return !mbRow ? 1 : mpTable->getAccessibleColumnCount(); 1207 } 1208 1209 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleRowDescription( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException) 1210 { 1211 return mpTable->getAccessibleRowDescription( nRow ); 1212 } 1213 1214 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnDescription( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1215 { 1216 return mpTable->getAccessibleColumnDescription( nColumn ); 1217 } 1218 1219 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1220 { 1221 return mpTable->getAccessibleRowExtentAt( nRow, nColumn ); 1222 } 1223 1224 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1225 { 1226 return mpTable->getAccessibleColumnExtentAt( nRow, nColumn ); 1227 } 1228 1229 Reference< XAccessibleTable > SAL_CALL AccessibleTableHeaderShape::getAccessibleRowHeaders( ) throw (RuntimeException) 1230 { 1231 Reference< XAccessibleTable > xRet; 1232 return xRet; 1233 } 1234 1235 Reference< XAccessibleTable > SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnHeaders( ) throw (RuntimeException) 1236 { 1237 Reference< XAccessibleTable > xRet; 1238 return xRet; 1239 } 1240 1241 Sequence< sal_Int32 > SAL_CALL AccessibleTableHeaderShape::getSelectedAccessibleRows( ) throw (RuntimeException) 1242 { 1243 sal_Int32 nRow = getAccessibleRowCount(); 1244 ::std::vector< sal_Bool > aSelected( nRow, sal_True ); 1245 sal_Int32 nCount = nRow; 1246 for( sal_Int32 i = 0; i < nRow; i++ ) 1247 { 1248 try 1249 { 1250 aSelected[i] = isAccessibleRowSelected( i ); 1251 } 1252 catch( ... ) 1253 { 1254 return Sequence< sal_Int32 >(); 1255 } 1256 1257 if( !aSelected[i] ) 1258 nCount--; 1259 } 1260 Sequence < sal_Int32 > aRet( nCount ); 1261 sal_Int32 *pRet = aRet.getArray(); 1262 sal_Int32 nPos = 0; 1263 size_t nSize = aSelected.size(); 1264 for( size_t i=0; i < nSize && nPos < nCount; i++ ) 1265 { 1266 if( aSelected[i] ) 1267 { 1268 *pRet++ = i; 1269 nPos++; 1270 } 1271 } 1272 1273 return aRet; 1274 } 1275 1276 Sequence< sal_Int32 > SAL_CALL AccessibleTableHeaderShape::getSelectedAccessibleColumns( ) throw (RuntimeException) 1277 { 1278 sal_Int32 nColumn = getAccessibleColumnCount(); 1279 ::std::vector< sal_Bool > aSelected( nColumn, sal_True ); 1280 sal_Int32 nCount = nColumn; 1281 for( sal_Int32 i = 0; i < nColumn; i++ ) 1282 { 1283 try 1284 { 1285 aSelected[i] = isAccessibleColumnSelected( i ); 1286 } 1287 catch( ... ) 1288 { 1289 return Sequence< sal_Int32 >(); 1290 } 1291 1292 if( !aSelected[i] ) 1293 nCount--; 1294 } 1295 Sequence < sal_Int32 > aRet( nCount ); 1296 sal_Int32 *pRet = aRet.getArray(); 1297 sal_Int32 nPos = 0; 1298 size_t nSize = aSelected.size(); 1299 for( size_t i=0; i < nSize && nPos < nCount; i++ ) 1300 { 1301 if( aSelected[i] ) 1302 { 1303 *pRet++ = i; 1304 nPos++; 1305 } 1306 } 1307 1308 return aRet; 1309 } 1310 1311 sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleRowSelected( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException) 1312 { 1313 return mpTable->isAccessibleRowSelected( nRow ); 1314 } 1315 1316 sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleColumnSelected( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1317 { 1318 return mpTable->isAccessibleColumnSelected( nColumn ); 1319 } 1320 1321 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1322 { 1323 return mpTable->getAccessibleCellAt( nRow, nColumn ); 1324 } 1325 1326 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleCaption( ) throw (RuntimeException) 1327 { 1328 return mpTable->getAccessibleCaption(); 1329 } 1330 1331 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleSummary( ) throw (RuntimeException) 1332 { 1333 return mpTable->getAccessibleSummary(); 1334 } 1335 1336 sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1337 { 1338 return mpTable->isAccessibleSelected( nRow, nColumn ); 1339 } 1340 1341 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException) 1342 { 1343 return mpTable->getAccessibleIndex( nRow, nColumn ); 1344 } 1345 1346 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRow( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1347 { 1348 return mpTable->getAccessibleRow( nChildIndex ); 1349 } 1350 1351 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumn( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1352 { 1353 return mpTable->getAccessibleColumn( nChildIndex ); 1354 } 1355 1356 //===== XAccessibleTableSelection ============================================ 1357 sal_Bool SAL_CALL AccessibleTableHeaderShape::selectRow( sal_Int32 row ) 1358 throw (IndexOutOfBoundsException, RuntimeException) 1359 { 1360 if( mbRow ) 1361 return mpTable->selectRow( row ); 1362 else 1363 { 1364 mpTable->clearAccessibleSelection(); 1365 sal_Int32 nIndex = mpTable->getAccessibleIndex( row, 0 ); 1366 mpTable->selectAccessibleChild( nIndex ); 1367 return sal_True; 1368 } 1369 } 1370 1371 sal_Bool SAL_CALL AccessibleTableHeaderShape::selectColumn( sal_Int32 column ) 1372 throw (IndexOutOfBoundsException, RuntimeException) 1373 { 1374 if( !mbRow ) 1375 return mpTable->selectColumn( column ); 1376 else 1377 { 1378 mpTable->clearAccessibleSelection(); 1379 sal_Int32 nIndex = mpTable->getAccessibleIndex( 0, column ); 1380 mpTable->selectAccessibleChild( nIndex ); 1381 return sal_True; 1382 } 1383 } 1384 1385 sal_Bool SAL_CALL AccessibleTableHeaderShape::unselectRow( sal_Int32 row ) 1386 throw (IndexOutOfBoundsException, RuntimeException) 1387 { 1388 if( mbRow ) 1389 return mpTable->unselectRow( row ); 1390 else 1391 { 1392 sal_Int32 nIndex = mpTable->getAccessibleIndex( row, 0 ); 1393 mpTable->deselectAccessibleChild( nIndex ); 1394 return sal_True; 1395 } 1396 } 1397 1398 sal_Bool SAL_CALL AccessibleTableHeaderShape::unselectColumn( sal_Int32 column ) 1399 throw (IndexOutOfBoundsException, RuntimeException) 1400 { 1401 if( !mbRow ) 1402 return mpTable->unselectColumn( column ); 1403 else 1404 { 1405 sal_Int32 nIndex = mpTable->getAccessibleIndex( 0, column ); 1406 mpTable->deselectAccessibleChild( nIndex ); 1407 return sal_True; 1408 } 1409 } 1410 } 1411