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_sw.hxx" 30 #include <vos/mutex.hxx> 31 #include <rtl/uuid.h> 32 #include <rtl/ustrbuf.hxx> 33 34 #include <list> 35 #include <set> 36 #include <com/sun/star/accessibility/AccessibleRole.hpp> 37 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 38 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 39 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> 40 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> 41 #include <unotools/accessiblestatesethelper.hxx> 42 #include <vcl/svapp.hxx> 43 #include <frmfmt.hxx> 44 #include <tabfrm.hxx> 45 #include <rowfrm.hxx> 46 #include <cellfrm.hxx> 47 #include <swtable.hxx> 48 #include <crsrsh.hxx> 49 #include <viscrs.hxx> 50 #include <hints.hxx> 51 #include <fesh.hxx> 52 #include <accfrmobjslist.hxx> 53 #include <accmap.hxx> 54 #include <access.hrc> 55 #include <acctable.hxx> 56 57 #include <com/sun/star/accessibility/XAccessibleText.hpp> 58 59 using namespace ::com::sun::star; 60 using namespace ::com::sun::star::accessibility; 61 using ::rtl::OUString; 62 using ::rtl::OUStringBuffer; 63 using namespace ::sw::access; 64 65 const sal_Char sServiceName[] = "com.sun.star.table.AccessibleTableView"; 66 const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleTableView"; 67 68 typedef ::std::less < sal_Int32 > Int32Less_Impl; 69 typedef ::std::set < sal_Int32, Int32Less_Impl > Int32Set_Impl; 70 71 typedef ::std::pair < sal_Int32, sal_Int32 > Int32Pair_Impl; 72 typedef ::std::list < Int32Pair_Impl > Int32PairList_Impl; 73 74 class SwAccTableSelHander_Impl 75 { 76 public: 77 virtual void Unselect( sal_Int32 nRowOrCol, sal_Int32 nExt ) = 0; 78 }; 79 80 81 //------------------------------------------------------------------------------ 82 83 class SwAccessibleTableData_Impl 84 { 85 SwAccessibleMap& mrAccMap; 86 Int32Set_Impl maRows; 87 Int32Set_Impl maColumns; 88 Int32PairList_Impl maExtents; // cell extends for event processing only 89 Point maTabFrmPos; 90 const SwTabFrm *mpTabFrm; 91 sal_Bool mbIsInPagePreview; 92 bool mbOnlyTableColumnHeader; 93 94 void CollectData( const SwFrm *pFrm ); 95 void CollectExtents( const SwFrm *pFrm ); 96 97 sal_Bool FindCell( const Point& rPos, const SwFrm *pFrm , 98 sal_Bool bExact, const SwFrm *& rFrm ) const; 99 100 void GetSelection( const Point& rTabPos, const SwRect& rArea, 101 const SwSelBoxes& rSelBoxes, const SwFrm *pFrm, 102 SwAccTableSelHander_Impl& rSelHdl, 103 sal_Bool bColumns ) const; 104 105 // --> OD 2007-06-27 #i77106# 106 inline bool IncludeRow( const SwFrm& rFrm ) const 107 { 108 return !mbOnlyTableColumnHeader || 109 mpTabFrm->IsInHeadline( rFrm ); 110 } 111 // <-- 112 public: 113 // --> OD 2007-06-27 #i77106# 114 // add third optional parameter <bOnlyTableColumnHeader>, default value <false> 115 SwAccessibleTableData_Impl( SwAccessibleMap& rAccMap, 116 const SwTabFrm *pTabFrm, 117 sal_Bool bIsInPagePreview, 118 bool bOnlyTableColumnHeader = false ); 119 // <-- 120 121 const Int32Set_Impl& GetRows() const { return maRows; } 122 const Int32Set_Impl& GetColumns() const { return maColumns; } 123 124 inline Int32Set_Impl::const_iterator GetRowIter( sal_Int32 nRow ) const; 125 inline Int32Set_Impl::const_iterator GetColumnIter( sal_Int32 nCol ) const; 126 127 const SwFrm *GetCell( sal_Int32 nRow, sal_Int32 nColumn, sal_Bool bExact, 128 SwAccessibleTable *pThis ) const 129 throw(lang::IndexOutOfBoundsException ); 130 const SwFrm *GetCellAtPos( sal_Int32 nLeft, sal_Int32 nTop, 131 sal_Bool bExact ) const; 132 inline sal_Int32 GetRowCount() const; 133 inline sal_Int32 GetColumnCount() const; 134 sal_Bool CompareExtents( const SwAccessibleTableData_Impl& r ) const; 135 136 void GetSelection( sal_Int32 nStart, sal_Int32 nEnd, 137 const SwSelBoxes& rSelBoxes, 138 SwAccTableSelHander_Impl& rSelHdl, 139 sal_Bool bColumns ) const; 140 141 void CheckRowAndCol( sal_Int32 nRow, sal_Int32 nCol, 142 SwAccessibleTable *pThis ) const 143 throw(lang::IndexOutOfBoundsException ); 144 145 void GetRowColumnAndExtent( const SwRect& rBox, 146 sal_Int32& rRow, sal_Int32& rColumn, 147 sal_Int32& rRowExtent, 148 sal_Int32& rColumnExtent ) const; 149 150 const Point& GetTablePos() const { return maTabFrmPos; } 151 void SetTablePos( const Point& rPos ) { maTabFrmPos = rPos; } 152 }; 153 154 void SwAccessibleTableData_Impl::CollectData( const SwFrm *pFrm ) 155 { 156 const SwAccessibleChildSList aList( *pFrm, mrAccMap ); 157 SwAccessibleChildSList::const_iterator aIter( aList.begin() ); 158 SwAccessibleChildSList::const_iterator aEndIter( aList.end() ); 159 while( aIter != aEndIter ) 160 { 161 const SwAccessibleChild& rLower = *aIter; 162 const SwFrm *pLower = rLower.GetSwFrm(); 163 if( pLower ) 164 { 165 if( pLower->IsRowFrm() ) 166 { 167 // --> OD 2007-06-27 #i77106# 168 if ( IncludeRow( *pLower ) ) 169 { 170 maRows.insert( pLower->Frm().Top() - maTabFrmPos.Y() ); 171 CollectData( pLower ); 172 } 173 // <-- 174 } 175 else if( pLower->IsCellFrm() && 176 rLower.IsAccessible( mbIsInPagePreview ) ) 177 { 178 maColumns.insert( pLower->Frm().Left() - maTabFrmPos.X() ); 179 } 180 else 181 { 182 CollectData( pLower ); 183 } 184 } 185 ++aIter; 186 } 187 } 188 189 void SwAccessibleTableData_Impl::CollectExtents( const SwFrm *pFrm ) 190 { 191 const SwAccessibleChildSList aList( *pFrm, mrAccMap ); 192 SwAccessibleChildSList::const_iterator aIter( aList.begin() ); 193 SwAccessibleChildSList::const_iterator aEndIter( aList.end() ); 194 while( aIter != aEndIter ) 195 { 196 const SwAccessibleChild& rLower = *aIter; 197 const SwFrm *pLower = rLower.GetSwFrm(); 198 if( pLower ) 199 { 200 if( pLower->IsCellFrm() && 201 rLower.IsAccessible( mbIsInPagePreview ) ) 202 { 203 sal_Int32 nRow, nCol; 204 Int32Pair_Impl aCellExtents; 205 GetRowColumnAndExtent( pLower->Frm(), nRow, nCol, 206 aCellExtents.first, 207 aCellExtents.second ); 208 209 maExtents.push_back( aCellExtents ); 210 } 211 else 212 { 213 // --> OD 2007-06-27 #i77106# 214 if ( !pLower->IsRowFrm() || 215 IncludeRow( *pLower ) ) 216 { 217 CollectExtents( pLower ); 218 } 219 // <-- 220 } 221 } 222 ++aIter; 223 } 224 } 225 226 sal_Bool SwAccessibleTableData_Impl::FindCell( 227 const Point& rPos, const SwFrm *pFrm, sal_Bool bExact, 228 const SwFrm *& rRet ) const 229 { 230 sal_Bool bFound = sal_False; 231 232 const SwAccessibleChildSList aList( *pFrm, mrAccMap ); 233 SwAccessibleChildSList::const_iterator aIter( aList.begin() ); 234 SwAccessibleChildSList::const_iterator aEndIter( aList.end() ); 235 while( !bFound && aIter != aEndIter ) 236 { 237 const SwAccessibleChild& rLower = *aIter; 238 const SwFrm *pLower = rLower.GetSwFrm(); 239 ASSERT( pLower, "child should be a frame" ); 240 if( pLower ) 241 { 242 if( rLower.IsAccessible( mbIsInPagePreview ) ) 243 { 244 ASSERT( pLower->IsCellFrm(), "lower is not a cell frame" ); 245 const SwRect& rFrm = pLower->Frm(); 246 if( rFrm.Right() >= rPos.X() && rFrm.Bottom() >= rPos.Y() ) 247 { 248 // We have found the cell 249 ASSERT( rFrm.Left() <= rPos.X() && rFrm.Top() <= rPos.Y(), 250 "find frame moved to far!" ); 251 bFound = sal_True; 252 if( !bExact || 253 (rFrm.Top() == rPos.Y() && rFrm.Left() == rPos.Y() ) ) 254 { 255 rRet = pLower; 256 } 257 } 258 } 259 else 260 { 261 // --> OD 2007-06-27 #i77106# 262 if ( !pLower->IsRowFrm() || 263 IncludeRow( *pLower ) ) 264 { 265 bFound = FindCell( rPos, pLower, bExact, rRet ); 266 } 267 // <-- 268 } 269 } 270 ++aIter; 271 } 272 273 return bFound; 274 } 275 276 void SwAccessibleTableData_Impl::GetSelection( 277 const Point& rTabPos, 278 const SwRect& rArea, 279 const SwSelBoxes& rSelBoxes, 280 const SwFrm *pFrm, 281 SwAccTableSelHander_Impl& rSelHdl, 282 sal_Bool bColumns ) const 283 { 284 const SwAccessibleChildSList aList( *pFrm, mrAccMap ); 285 SwAccessibleChildSList::const_iterator aIter( aList.begin() ); 286 SwAccessibleChildSList::const_iterator aEndIter( aList.end() ); 287 while( aIter != aEndIter ) 288 { 289 const SwAccessibleChild& rLower = *aIter; 290 const SwFrm *pLower = rLower.GetSwFrm(); 291 ASSERT( pLower, "child should be a frame" ); 292 const SwRect& rBox = rLower.GetBox( mrAccMap ); 293 if( pLower && rBox.IsOver( rArea ) ) 294 { 295 if( rLower.IsAccessible( mbIsInPagePreview ) ) 296 { 297 ASSERT( pLower->IsCellFrm(), "lower is not a cell frame" ); 298 const SwCellFrm *pCFrm = 299 static_cast < const SwCellFrm * >( pLower ); 300 SwTableBox *pBox = 301 const_cast< SwTableBox *>( pCFrm->GetTabBox() ); //SVPtrArr! 302 if( !rSelBoxes.Seek_Entry( pBox ) ) 303 { 304 const Int32Set_Impl rRowsOrCols = 305 bColumns ? maColumns : maRows; 306 307 sal_Int32 nPos = bColumns ? (rBox.Left() - rTabPos.X()) 308 : (rBox.Top() - rTabPos.Y()); 309 Int32Set_Impl::const_iterator aSttRowOrCol( 310 rRowsOrCols.lower_bound( nPos ) ); 311 sal_Int32 nRowOrCol = 312 static_cast< sal_Int32 >( ::std::distance( 313 rRowsOrCols.begin(), aSttRowOrCol ) ); 314 315 nPos = bColumns ? (rBox.Right() - rTabPos.X()) 316 : (rBox.Bottom() - rTabPos.Y()); 317 Int32Set_Impl::const_iterator aEndRowOrCol( 318 rRowsOrCols.upper_bound( nPos ) ); 319 sal_Int32 nExt = 320 static_cast< sal_Int32 >( ::std::distance( 321 aSttRowOrCol, aEndRowOrCol ) ); 322 323 rSelHdl.Unselect( nRowOrCol, nExt ); 324 } 325 } 326 else 327 { 328 // --> OD 2007-06-27 #i77106# 329 if ( !pLower->IsRowFrm() || 330 IncludeRow( *pLower ) ) 331 { 332 GetSelection( rTabPos, rArea, rSelBoxes, pLower, rSelHdl, 333 bColumns ); 334 } 335 // <-- 336 } 337 } 338 ++aIter; 339 } 340 } 341 342 const SwFrm *SwAccessibleTableData_Impl::GetCell( 343 sal_Int32 nRow, sal_Int32 nColumn, sal_Bool, 344 SwAccessibleTable *pThis ) const 345 throw(lang::IndexOutOfBoundsException ) 346 { 347 CheckRowAndCol( nRow, nColumn, pThis ); 348 349 Int32Set_Impl::const_iterator aSttCol( GetColumnIter( nColumn ) ); 350 Int32Set_Impl::const_iterator aSttRow( GetRowIter( nRow ) ); 351 const SwFrm *pCellFrm = GetCellAtPos( *aSttCol, *aSttRow, sal_False ); 352 353 return pCellFrm; 354 } 355 356 void SwAccessibleTableData_Impl::GetSelection( 357 sal_Int32 nStart, sal_Int32 nEnd, 358 const SwSelBoxes& rSelBoxes, 359 SwAccTableSelHander_Impl& rSelHdl, 360 sal_Bool bColumns ) const 361 { 362 SwRect aArea( mpTabFrm->Frm() ); 363 Point aPos( aArea.Pos() ); 364 365 const Int32Set_Impl& rRowsOrColumns = bColumns ? maColumns : maRows; 366 if( nStart > 0 ) 367 { 368 Int32Set_Impl::const_iterator aStt( rRowsOrColumns.begin() ); 369 ::std::advance( aStt, 370 static_cast< Int32Set_Impl::difference_type >( nStart ) ); 371 if( bColumns ) 372 aArea.Left( *aStt + aPos.X() ); 373 else 374 aArea.Top( *aStt + aPos.Y() ); 375 } 376 if( nEnd < static_cast< sal_Int32 >( rRowsOrColumns.size() ) ) 377 { 378 Int32Set_Impl::const_iterator aEnd( rRowsOrColumns.begin() ); 379 ::std::advance( aEnd, 380 static_cast< Int32Set_Impl::difference_type >( nEnd ) ); 381 if( bColumns ) 382 aArea.Right( *aEnd + aPos.X() - 1 ); 383 else 384 aArea.Bottom( *aEnd + aPos.Y() - 1 ); 385 } 386 387 GetSelection( aPos, aArea, rSelBoxes, mpTabFrm, rSelHdl, bColumns ); 388 } 389 390 const SwFrm *SwAccessibleTableData_Impl::GetCellAtPos( 391 sal_Int32 nLeft, sal_Int32 nTop, sal_Bool bExact ) const 392 { 393 Point aPos( mpTabFrm->Frm().Pos() ); 394 aPos.Move( nLeft, nTop ); 395 const SwFrm *pRet = 0; 396 FindCell( aPos, mpTabFrm, bExact, pRet ); 397 398 return pRet; 399 } 400 401 inline sal_Int32 SwAccessibleTableData_Impl::GetRowCount() const 402 { 403 return static_cast< sal_Int32 >( maRows.size() ); 404 } 405 406 inline sal_Int32 SwAccessibleTableData_Impl::GetColumnCount() const 407 { 408 return static_cast< sal_Int32 >( maColumns.size() ); 409 } 410 411 sal_Bool SwAccessibleTableData_Impl::CompareExtents( 412 const SwAccessibleTableData_Impl& rCmp ) const 413 { 414 if( maExtents.size() != rCmp.maExtents.size() ) 415 return sal_False; 416 417 Int32PairList_Impl::const_iterator aIter( maExtents.begin() ); 418 Int32PairList_Impl::const_iterator aEndIter( maExtents.end() ); 419 Int32PairList_Impl::const_iterator aCmpIter( rCmp.maExtents.begin() ); 420 while( aIter != aEndIter ) 421 { 422 if( *aIter != *aCmpIter ) 423 return sal_False; 424 425 ++aIter; 426 ++aCmpIter; 427 } 428 429 return sal_True; 430 } 431 432 SwAccessibleTableData_Impl::SwAccessibleTableData_Impl( SwAccessibleMap& rAccMap, 433 const SwTabFrm *pTabFrm, 434 sal_Bool bIsInPagePreview, 435 bool bOnlyTableColumnHeader ) 436 : mrAccMap( rAccMap ) 437 , maTabFrmPos( pTabFrm->Frm().Pos() ) 438 , mpTabFrm( pTabFrm ) 439 , mbIsInPagePreview( bIsInPagePreview ) 440 , mbOnlyTableColumnHeader( bOnlyTableColumnHeader ) 441 { 442 CollectData( mpTabFrm ); 443 CollectExtents( mpTabFrm ); 444 } 445 446 inline Int32Set_Impl::const_iterator SwAccessibleTableData_Impl::GetRowIter( 447 sal_Int32 nRow ) const 448 { 449 Int32Set_Impl::const_iterator aCol( GetRows().begin() ); 450 if( nRow > 0 ) 451 { 452 ::std::advance( aCol, 453 static_cast< Int32Set_Impl::difference_type >( nRow ) ); 454 } 455 return aCol; 456 } 457 458 inline Int32Set_Impl::const_iterator SwAccessibleTableData_Impl::GetColumnIter( 459 sal_Int32 nColumn ) const 460 { 461 Int32Set_Impl::const_iterator aCol = GetColumns().begin(); 462 if( nColumn > 0 ) 463 { 464 ::std::advance( aCol, 465 static_cast< Int32Set_Impl::difference_type >( nColumn ) ); 466 } 467 return aCol; 468 } 469 470 void SwAccessibleTableData_Impl::CheckRowAndCol( 471 sal_Int32 nRow, sal_Int32 nCol, SwAccessibleTable *pThis ) const 472 throw(lang::IndexOutOfBoundsException ) 473 { 474 if( ( nRow < 0 || nRow >= static_cast< sal_Int32 >( maRows.size() ) ) || 475 ( nCol < 0 || nCol >= static_cast< sal_Int32 >( maColumns.size() ) ) ) 476 { 477 uno::Reference < XAccessibleTable > xThis( pThis ); 478 lang::IndexOutOfBoundsException aExcept( 479 OUString( RTL_CONSTASCII_USTRINGPARAM( 480 "row or column index out of range") ), 481 xThis ); 482 throw aExcept; 483 } 484 } 485 486 void SwAccessibleTableData_Impl::GetRowColumnAndExtent( 487 const SwRect& rBox, 488 sal_Int32& rRow, sal_Int32& rColumn, 489 sal_Int32& rRowExtent, sal_Int32& rColumnExtent ) const 490 { 491 Int32Set_Impl::const_iterator aStt( 492 maRows.lower_bound( rBox.Top() - maTabFrmPos.Y() ) ); 493 Int32Set_Impl::const_iterator aEnd( 494 maRows.upper_bound( rBox.Bottom() - maTabFrmPos.Y() ) ); 495 rRow = 496 static_cast< sal_Int32 >( ::std::distance( maRows.begin(), aStt ) ); 497 rRowExtent = 498 static_cast< sal_Int32 >( ::std::distance( aStt, aEnd ) ); 499 500 aStt = maColumns.lower_bound( rBox.Left() - maTabFrmPos.X() ); 501 aEnd = maColumns.upper_bound( rBox.Right() - maTabFrmPos.X() ); 502 rColumn = 503 static_cast< sal_Int32 >( ::std::distance( maColumns.begin(), aStt ) ); 504 rColumnExtent = 505 static_cast< sal_Int32 >( ::std::distance( aStt, aEnd ) ); 506 } 507 508 //------------------------------------------------------------------------------ 509 510 class SwAccSingleTableSelHander_Impl : public SwAccTableSelHander_Impl 511 { 512 sal_Bool bSelected; 513 514 public: 515 516 inline SwAccSingleTableSelHander_Impl(); 517 518 inline sal_Bool IsSelected() const { return bSelected; } 519 520 virtual void Unselect( sal_Int32, sal_Int32 ); 521 }; 522 523 inline SwAccSingleTableSelHander_Impl::SwAccSingleTableSelHander_Impl() : 524 bSelected( sal_True ) 525 { 526 } 527 528 void SwAccSingleTableSelHander_Impl::Unselect( sal_Int32, sal_Int32 ) 529 { 530 bSelected = sal_False; 531 } 532 533 //------------------------------------------------------------------------------ 534 535 class SwAccAllTableSelHander_Impl : public SwAccTableSelHander_Impl 536 537 { 538 ::std::vector< sal_Bool > aSelected; 539 sal_Int32 nCount; 540 541 public: 542 543 inline SwAccAllTableSelHander_Impl( sal_Int32 nSize ); 544 545 uno::Sequence < sal_Int32 > GetSelSequence(); 546 547 virtual void Unselect( sal_Int32 nRowOrCol, sal_Int32 nExt ); 548 virtual ~SwAccAllTableSelHander_Impl(); 549 }; 550 551 SwAccAllTableSelHander_Impl::~SwAccAllTableSelHander_Impl() 552 { 553 } 554 555 inline SwAccAllTableSelHander_Impl::SwAccAllTableSelHander_Impl( sal_Int32 nSize ) : 556 aSelected( nSize, sal_True ), 557 nCount( nSize ) 558 { 559 } 560 561 uno::Sequence < sal_Int32 > SwAccAllTableSelHander_Impl::GetSelSequence() 562 { 563 ASSERT( nCount >= 0, "underflow" ); 564 uno::Sequence < sal_Int32 > aRet( nCount ); 565 sal_Int32 *pRet = aRet.getArray(); 566 sal_Int32 nPos = 0; 567 size_t nSize = aSelected.size(); 568 for( size_t i=0; i < nSize && nPos < nCount; i++ ) 569 { 570 if( aSelected[i] ) 571 { 572 *pRet++ = i; 573 nPos++; 574 } 575 } 576 577 ASSERT( nPos == nCount, "count is wrong" ); 578 579 return aRet; 580 } 581 582 void SwAccAllTableSelHander_Impl::Unselect( sal_Int32 nRowOrCol, 583 sal_Int32 nExt ) 584 { 585 ASSERT( static_cast< size_t >( nRowOrCol ) < aSelected.size(), 586 "index to large" ); 587 ASSERT( static_cast< size_t >( nRowOrCol+nExt ) <= aSelected.size(), 588 "extent to large" ); 589 while( nExt ) 590 { 591 if( aSelected[static_cast< size_t >( nRowOrCol )] ) 592 { 593 aSelected[static_cast< size_t >( nRowOrCol )] = sal_False; 594 nCount--; 595 } 596 nExt--; 597 nRowOrCol++; 598 } 599 } 600 601 //------------------------------------------------------------------------------ 602 603 const SwSelBoxes *SwAccessibleTable::GetSelBoxes() const 604 { 605 const SwSelBoxes *pSelBoxes = 0; 606 const SwCrsrShell *pCSh = GetCrsrShell(); 607 if( (pCSh != NULL) && pCSh->IsTableMode() ) 608 { 609 pSelBoxes = &pCSh->GetTableCrsr()->GetBoxes(); 610 } 611 612 return pSelBoxes; 613 } 614 615 void SwAccessibleTable::FireTableChangeEvent( 616 const SwAccessibleTableData_Impl& rTableData ) 617 { 618 AccessibleTableModelChange aModelChange; 619 aModelChange.Type = AccessibleTableModelChangeType::UPDATE; 620 aModelChange.FirstRow = 0; 621 aModelChange.LastRow = rTableData.GetRowCount() - 1; 622 aModelChange.FirstColumn = 0; 623 aModelChange.LastColumn = rTableData.GetColumnCount() - 1; 624 625 AccessibleEventObject aEvent; 626 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED; 627 aEvent.NewValue <<= aModelChange; 628 629 FireAccessibleEvent( aEvent ); 630 } 631 632 633 const SwTableBox* SwAccessibleTable::GetTableBox( sal_Int32 nChildIndex ) const 634 { 635 DBG_ASSERT( nChildIndex >= 0, "Illegal child index." ); 636 // --> OD 2007-06-27 #i77106# 637 DBG_ASSERT( nChildIndex < const_cast<SwAccessibleTable*>(this)->getAccessibleChildCount(), "Illegal child index." ); 638 // <-- 639 640 const SwTableBox* pBox = NULL; 641 642 // get table box for 'our' table cell 643 SwAccessibleChild aCell( GetChild( *(const_cast<SwAccessibleMap*>(GetMap())), nChildIndex ) ); 644 if( aCell.GetSwFrm() ) 645 { 646 const SwFrm* pChildFrm = aCell.GetSwFrm(); 647 if( (pChildFrm != NULL) && pChildFrm->IsCellFrm() ) 648 { 649 const SwCellFrm* pCellFrm = 650 static_cast<const SwCellFrm*>( pChildFrm ); 651 pBox = pCellFrm->GetTabBox(); 652 } 653 } 654 655 DBG_ASSERT( pBox != NULL, "We need the table box." ); 656 return pBox; 657 } 658 659 sal_Bool SwAccessibleTable::IsChildSelected( sal_Int32 nChildIndex ) const 660 { 661 sal_Bool bRet = sal_False; 662 const SwSelBoxes* pSelBoxes = GetSelBoxes(); 663 if( pSelBoxes ) 664 { 665 const SwTableBox* pBox = GetTableBox( nChildIndex ); 666 DBG_ASSERT( pBox != NULL, "We need the table box." ); 667 bRet = pSelBoxes->Seek_Entry( const_cast<SwTableBox*>( pBox ) ); 668 } 669 670 return bRet; 671 } 672 673 sal_Int32 SwAccessibleTable::GetIndexOfSelectedChild( 674 sal_Int32 nSelectedChildIndex ) const 675 { 676 // iterate over all children to n-th isAccessibleChildSelected() 677 // --> OD 2007-06-27 #i77106# 678 sal_Int32 nChildren = const_cast<SwAccessibleTable*>(this)->getAccessibleChildCount(); 679 // <-- 680 if( nSelectedChildIndex >= nChildren ) 681 return -1L; 682 683 sal_Int32 n = 0; 684 while( n < nChildren ) 685 { 686 if( IsChildSelected( n ) ) 687 { 688 if( 0 == nSelectedChildIndex ) 689 break; 690 else 691 --nSelectedChildIndex; 692 } 693 ++n; 694 } 695 696 return n < nChildren ? n : -1L; 697 } 698 699 void SwAccessibleTable::GetStates( 700 ::utl::AccessibleStateSetHelper& rStateSet ) 701 { 702 SwAccessibleContext::GetStates( rStateSet ); 703 704 // MULTISELECTABLE 705 SwCrsrShell* pCrsrShell = GetCrsrShell(); 706 if( pCrsrShell ) 707 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE ); 708 } 709 710 SwAccessibleTable::SwAccessibleTable( 711 SwAccessibleMap* pInitMap, 712 const SwTabFrm* pTabFrm ) : 713 SwAccessibleContext( pInitMap, AccessibleRole::TABLE, pTabFrm ), 714 mpTableData( 0 ) 715 { 716 vos::OGuard aGuard(Application::GetSolarMutex()); 717 718 const SwFrmFmt *pFrmFmt = pTabFrm->GetFmt(); 719 const_cast< SwFrmFmt * >( pFrmFmt )->Add( this ); 720 const String& rName = pFrmFmt->GetName(); 721 722 OUStringBuffer aBuffer( rName.Len() + 4 ); 723 aBuffer.append( OUString(rName) ); 724 aBuffer.append( static_cast<sal_Unicode>( '-' ) ); 725 aBuffer.append( static_cast<sal_Int32>( pTabFrm->GetPhyPageNum() ) ); 726 727 SetName( aBuffer.makeStringAndClear() ); 728 729 OUString sArg1( static_cast< const SwTabFrm * >( GetFrm() ) 730 ->GetFmt()->GetName() ); 731 OUString sArg2( GetFormattedPageNumber() ); 732 733 sDesc = GetResource( STR_ACCESS_TABLE_DESC, &sArg1, &sArg2 ); 734 } 735 736 SwAccessibleTable::~SwAccessibleTable() 737 { 738 vos::OGuard aGuard(Application::GetSolarMutex()); 739 740 delete mpTableData; 741 } 742 743 void SwAccessibleTable::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew) 744 { 745 sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ; 746 const SwTabFrm *pTabFrm = static_cast< const SwTabFrm * >( GetFrm() ); 747 switch( nWhich ) 748 { 749 case RES_NAME_CHANGED: 750 if( pTabFrm ) 751 { 752 const SwFrmFmt *pFrmFmt = pTabFrm->GetFmt(); 753 ASSERT( pFrmFmt == GetRegisteredIn(), "invalid frame" ); 754 755 OUString sOldName( GetName() ); 756 757 const String& rNewTabName = pFrmFmt->GetName(); 758 OUStringBuffer aBuffer( rNewTabName.Len() + 4 ); 759 aBuffer.append( OUString(rNewTabName) ); 760 aBuffer.append( static_cast<sal_Unicode>( '-' ) ); 761 aBuffer.append( static_cast<sal_Int32>( pTabFrm->GetPhyPageNum() ) ); 762 763 SetName( aBuffer.makeStringAndClear() ); 764 if( sOldName != GetName() ) 765 { 766 AccessibleEventObject aEvent; 767 aEvent.EventId = AccessibleEventId::NAME_CHANGED; 768 aEvent.OldValue <<= sOldName; 769 aEvent.NewValue <<= GetName(); 770 FireAccessibleEvent( aEvent ); 771 } 772 773 OUString sOldDesc( sDesc ); 774 OUString sArg1( rNewTabName ); 775 OUString sArg2( GetFormattedPageNumber() ); 776 777 sDesc = GetResource( STR_ACCESS_TABLE_DESC, &sArg1, &sArg2 ); 778 if( sDesc != sOldDesc ) 779 { 780 AccessibleEventObject aEvent; 781 aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED; 782 aEvent.OldValue <<= sOldDesc; 783 aEvent.NewValue <<= sDesc; 784 FireAccessibleEvent( aEvent ); 785 } 786 } 787 break; 788 789 case RES_OBJECTDYING: 790 // mba: it seems that this class intentionally does not call code in base class SwClient 791 if( GetRegisteredIn() == 792 static_cast< SwModify *>( static_cast< const SwPtrMsgPoolItem * >( pOld )->pObject ) ) 793 GetRegisteredInNonConst()->Remove( this ); 794 break; 795 796 default: 797 // mba: former call to base class method removed as it is meant to handle only RES_OBJECTDYING 798 break; 799 } 800 } 801 802 uno::Any SwAccessibleTable::queryInterface( const uno::Type& rType ) 803 throw (uno::RuntimeException) 804 { 805 uno::Any aRet; 806 if ( rType == ::getCppuType( static_cast< uno::Reference< XAccessibleTable > * >( 0 ) ) ) 807 { 808 uno::Reference<XAccessibleTable> xThis( this ); 809 aRet <<= xThis; 810 } 811 else if ( rType == ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) ) ) 812 { 813 uno::Reference<XAccessibleSelection> xSelection( this ); 814 aRet <<= xSelection; 815 } 816 else 817 { 818 aRet = SwAccessibleContext::queryInterface(rType); 819 } 820 821 return aRet; 822 } 823 824 //====== XTypeProvider ==================================================== 825 uno::Sequence< uno::Type > SAL_CALL SwAccessibleTable::getTypes() 826 throw(uno::RuntimeException) 827 { 828 uno::Sequence< uno::Type > aTypes( SwAccessibleContext::getTypes() ); 829 830 sal_Int32 nIndex = aTypes.getLength(); 831 aTypes.realloc( nIndex + 2 ); 832 833 uno::Type* pTypes = aTypes.getArray(); 834 pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) ); 835 pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleTable > * >( 0 ) ); 836 837 return aTypes; 838 } 839 840 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleTable::getImplementationId() 841 throw(uno::RuntimeException) 842 { 843 vos::OGuard aGuard(Application::GetSolarMutex()); 844 static uno::Sequence< sal_Int8 > aId( 16 ); 845 static sal_Bool bInit = sal_False; 846 if(!bInit) 847 { 848 rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True ); 849 bInit = sal_True; 850 } 851 return aId; 852 } 853 854 // --> OD 2007-06-28 #i77106# 855 SwAccessibleTableData_Impl* SwAccessibleTable::CreateNewTableData() 856 { 857 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( GetFrm() ); 858 return new SwAccessibleTableData_Impl( *GetMap(), pTabFrm, IsInPagePreview() ); 859 } 860 // <-- 861 862 void SwAccessibleTable::UpdateTableData() 863 { 864 // --> OD 2007-06-28 #i77106# - usage of new method <CreateNewTableData()> 865 delete mpTableData; 866 mpTableData = CreateNewTableData(); 867 // <-- 868 } 869 870 void SwAccessibleTable::ClearTableData() 871 { 872 delete mpTableData; 873 mpTableData = 0; 874 } 875 876 OUString SAL_CALL SwAccessibleTable::getAccessibleDescription (void) 877 throw (uno::RuntimeException) 878 { 879 vos::OGuard aGuard(Application::GetSolarMutex()); 880 881 CHECK_FOR_DEFUNC( XAccessibleContext ) 882 883 return sDesc; 884 } 885 886 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRowCount() 887 throw (uno::RuntimeException) 888 { 889 vos::OGuard aGuard(Application::GetSolarMutex()); 890 891 CHECK_FOR_DEFUNC( XAccessibleTable ) 892 893 return GetTableData().GetRowCount(); 894 } 895 896 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumnCount( ) 897 throw (uno::RuntimeException) 898 { 899 vos::OGuard aGuard(Application::GetSolarMutex()); 900 901 CHECK_FOR_DEFUNC( XAccessibleTable ) 902 903 return GetTableData().GetColumnCount(); 904 } 905 906 OUString SAL_CALL SwAccessibleTable::getAccessibleRowDescription( 907 sal_Int32 nRow ) 908 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 909 { 910 // --> OD 2010-03-10 #i87532# 911 // determine table cell in <nRow>th row and in first column of row header table 912 // and return its text content. 913 OUString sRowDesc; 914 915 GetTableData().CheckRowAndCol(nRow, 0, this); 916 917 uno::Reference< XAccessibleTable > xTableRowHeader = getAccessibleRowHeaders(); 918 if ( xTableRowHeader.is() ) 919 { 920 uno::Reference< XAccessible > xRowHeaderCell = 921 xTableRowHeader->getAccessibleCellAt( nRow, 0 ); 922 ASSERT( xRowHeaderCell.is(), 923 "<SwAccessibleTable::getAccessibleRowDescription(..)> - missing row header cell -> serious issue." ); 924 uno::Reference< XAccessibleContext > xRowHeaderCellContext = 925 xRowHeaderCell->getAccessibleContext(); 926 const sal_Int32 nCellChildCount( xRowHeaderCellContext->getAccessibleChildCount() ); 927 for ( sal_Int32 nChildIndex = 0; nChildIndex < nCellChildCount; ++nChildIndex ) 928 { 929 uno::Reference< XAccessible > xChild = xRowHeaderCellContext->getAccessibleChild( nChildIndex ); 930 uno::Reference< XAccessibleText > xChildText( xChild, uno::UNO_QUERY ); 931 if ( xChildText.is() ) 932 { 933 sRowDesc = sRowDesc + xChildText->getText(); 934 } 935 } 936 } 937 938 return sRowDesc; 939 // <-- 940 } 941 942 OUString SAL_CALL SwAccessibleTable::getAccessibleColumnDescription( 943 sal_Int32 nColumn ) 944 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 945 { 946 // --> OD 2010-03-10 #i87532# 947 // determine table cell in first row and in <nColumn>th column of column header table 948 // and return its text content. 949 OUString sColumnDesc; 950 951 GetTableData().CheckRowAndCol(0, nColumn, this); 952 953 uno::Reference< XAccessibleTable > xTableColumnHeader = getAccessibleColumnHeaders(); 954 if ( xTableColumnHeader.is() ) 955 { 956 uno::Reference< XAccessible > xColumnHeaderCell = 957 xTableColumnHeader->getAccessibleCellAt( 0, nColumn ); 958 ASSERT( xColumnHeaderCell.is(), 959 "<SwAccessibleTable::getAccessibleColumnDescription(..)> - missing column header cell -> serious issue." ); 960 uno::Reference< XAccessibleContext > xColumnHeaderCellContext = 961 xColumnHeaderCell->getAccessibleContext(); 962 const sal_Int32 nCellChildCount( xColumnHeaderCellContext->getAccessibleChildCount() ); 963 for ( sal_Int32 nChildIndex = 0; nChildIndex < nCellChildCount; ++nChildIndex ) 964 { 965 uno::Reference< XAccessible > xChild = xColumnHeaderCellContext->getAccessibleChild( nChildIndex ); 966 uno::Reference< XAccessibleText > xChildText( xChild, uno::UNO_QUERY ); 967 if ( xChildText.is() ) 968 { 969 sColumnDesc = sColumnDesc + xChildText->getText(); 970 } 971 } 972 } 973 974 return sColumnDesc; 975 // <-- 976 } 977 978 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRowExtentAt( 979 sal_Int32 nRow, sal_Int32 nColumn ) 980 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 981 { 982 sal_Int32 nExtend = -1; 983 984 vos::OGuard aGuard(Application::GetSolarMutex()); 985 986 CHECK_FOR_DEFUNC( XAccessibleTable ) 987 988 GetTableData().CheckRowAndCol( nRow, nColumn, this ); 989 990 Int32Set_Impl::const_iterator aSttCol( 991 GetTableData().GetColumnIter( nColumn ) ); 992 Int32Set_Impl::const_iterator aSttRow( 993 GetTableData().GetRowIter( nRow ) ); 994 const SwFrm *pCellFrm = GetTableData().GetCellAtPos( *aSttCol, *aSttRow, 995 sal_False ); 996 if( pCellFrm ) 997 { 998 sal_Int32 nBottom = pCellFrm->Frm().Bottom(); 999 nBottom -= GetFrm()->Frm().Top(); 1000 Int32Set_Impl::const_iterator aEndRow( 1001 GetTableData().GetRows().upper_bound( nBottom ) ); 1002 nExtend = 1003 static_cast< sal_Int32 >( ::std::distance( aSttRow, aEndRow ) ); 1004 } 1005 1006 return nExtend; 1007 } 1008 1009 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumnExtentAt( 1010 sal_Int32 nRow, sal_Int32 nColumn ) 1011 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1012 { 1013 sal_Int32 nExtend = -1; 1014 1015 vos::OGuard aGuard(Application::GetSolarMutex()); 1016 1017 CHECK_FOR_DEFUNC( XAccessibleTable ) 1018 1019 GetTableData().CheckRowAndCol( nRow, nColumn, this ); 1020 1021 Int32Set_Impl::const_iterator aSttCol( 1022 GetTableData().GetColumnIter( nColumn ) ); 1023 Int32Set_Impl::const_iterator aSttRow( 1024 GetTableData().GetRowIter( nRow ) ); 1025 const SwFrm *pCellFrm = GetTableData().GetCellAtPos( *aSttCol, *aSttRow, 1026 sal_False ); 1027 if( pCellFrm ) 1028 { 1029 sal_Int32 nRight = pCellFrm->Frm().Right(); 1030 nRight -= GetFrm()->Frm().Left(); 1031 Int32Set_Impl::const_iterator aEndCol( 1032 GetTableData().GetColumns().upper_bound( nRight ) ); 1033 nExtend = 1034 static_cast< sal_Int32 >( ::std::distance( aSttCol, aEndCol ) ); 1035 } 1036 1037 return nExtend; 1038 } 1039 1040 uno::Reference< XAccessibleTable > SAL_CALL 1041 SwAccessibleTable::getAccessibleRowHeaders( ) 1042 throw (uno::RuntimeException) 1043 { 1044 // Row headers aren't supported 1045 return uno::Reference< XAccessibleTable >(); 1046 } 1047 1048 uno::Reference< XAccessibleTable > SAL_CALL 1049 SwAccessibleTable::getAccessibleColumnHeaders( ) 1050 throw (uno::RuntimeException) 1051 { 1052 // --> OD 2010-03-10 #i87532# 1053 // assure that return accesible object is empty, if no column header exists. 1054 SwAccessibleTableColHeaders* pTableColHeaders = 1055 new SwAccessibleTableColHeaders( GetMap(), static_cast< const SwTabFrm *>( GetFrm() ) ); 1056 uno::Reference< XAccessibleTable > xTableColumnHeaders( pTableColHeaders ); 1057 if ( pTableColHeaders->getAccessibleChildCount() <= 0 ) 1058 { 1059 return uno::Reference< XAccessibleTable >(); 1060 } 1061 1062 return xTableColumnHeaders; 1063 // <-- 1064 } 1065 1066 uno::Sequence< sal_Int32 > SAL_CALL SwAccessibleTable::getSelectedAccessibleRows() 1067 throw (uno::RuntimeException) 1068 { 1069 vos::OGuard aGuard(Application::GetSolarMutex()); 1070 1071 CHECK_FOR_DEFUNC( XAccessibleTable ) 1072 1073 const SwSelBoxes *pSelBoxes = GetSelBoxes(); 1074 if( pSelBoxes ) 1075 { 1076 sal_Int32 nRows = GetTableData().GetRowCount(); 1077 SwAccAllTableSelHander_Impl aSelRows( nRows ); 1078 1079 GetTableData().GetSelection( 0, nRows, *pSelBoxes, aSelRows, 1080 sal_False ); 1081 1082 return aSelRows.GetSelSequence(); 1083 } 1084 else 1085 { 1086 return uno::Sequence< sal_Int32 >( 0 ); 1087 } 1088 } 1089 1090 uno::Sequence< sal_Int32 > SAL_CALL SwAccessibleTable::getSelectedAccessibleColumns() 1091 throw (uno::RuntimeException) 1092 { 1093 vos::OGuard aGuard(Application::GetSolarMutex()); 1094 1095 CHECK_FOR_DEFUNC( XAccessibleTable ) 1096 1097 const SwSelBoxes *pSelBoxes = GetSelBoxes(); 1098 if( pSelBoxes ) 1099 { 1100 sal_Int32 nCols = GetTableData().GetColumnCount(); 1101 SwAccAllTableSelHander_Impl aSelCols( nCols ); 1102 1103 GetTableData().GetSelection( 0, nCols, *pSelBoxes, aSelCols, sal_True ); 1104 1105 return aSelCols.GetSelSequence(); 1106 } 1107 else 1108 { 1109 return uno::Sequence< sal_Int32 >( 0 ); 1110 } 1111 } 1112 1113 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleRowSelected( sal_Int32 nRow ) 1114 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1115 { 1116 vos::OGuard aGuard(Application::GetSolarMutex()); 1117 1118 CHECK_FOR_DEFUNC( XAccessibleTable ) 1119 1120 GetTableData().CheckRowAndCol( nRow, 0, this ); 1121 1122 sal_Bool bRet; 1123 const SwSelBoxes *pSelBoxes = GetSelBoxes(); 1124 if( pSelBoxes ) 1125 { 1126 SwAccSingleTableSelHander_Impl aSelRow; 1127 GetTableData().GetSelection( nRow, nRow+1, *pSelBoxes, aSelRow, 1128 sal_False ); 1129 bRet = aSelRow.IsSelected(); 1130 } 1131 else 1132 { 1133 bRet = sal_False; 1134 } 1135 1136 return bRet; 1137 } 1138 1139 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleColumnSelected( 1140 sal_Int32 nColumn ) 1141 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1142 { 1143 vos::OGuard aGuard(Application::GetSolarMutex()); 1144 1145 CHECK_FOR_DEFUNC( XAccessibleTable ) 1146 1147 GetTableData().CheckRowAndCol( 0, nColumn, this ); 1148 1149 sal_Bool bRet; 1150 const SwSelBoxes *pSelBoxes = GetSelBoxes(); 1151 if( pSelBoxes ) 1152 { 1153 SwAccSingleTableSelHander_Impl aSelCol; 1154 1155 GetTableData().GetSelection( nColumn, nColumn+1, *pSelBoxes, aSelCol, 1156 sal_True ); 1157 bRet = aSelCol.IsSelected(); 1158 } 1159 else 1160 { 1161 bRet = sal_False; 1162 } 1163 1164 return bRet; 1165 } 1166 1167 uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleCellAt( 1168 sal_Int32 nRow, sal_Int32 nColumn ) 1169 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1170 { 1171 uno::Reference< XAccessible > xRet; 1172 1173 vos::OGuard aGuard(Application::GetSolarMutex()); 1174 1175 CHECK_FOR_DEFUNC( XAccessibleTable ) 1176 1177 const SwFrm *pCellFrm = 1178 GetTableData().GetCell( nRow, nColumn, sal_False, this ); 1179 if( pCellFrm ) 1180 xRet = GetMap()->GetContext( pCellFrm, sal_True ); 1181 1182 return xRet; 1183 } 1184 1185 uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleCaption() 1186 throw (uno::RuntimeException) 1187 { 1188 // captions aren't supported 1189 return uno::Reference< XAccessible >(); 1190 } 1191 1192 uno::Reference< XAccessible > SAL_CALL SwAccessibleTable::getAccessibleSummary() 1193 throw (uno::RuntimeException) 1194 { 1195 // summaries aren't supported 1196 return uno::Reference< XAccessible >(); 1197 } 1198 1199 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleSelected( 1200 sal_Int32 nRow, sal_Int32 nColumn ) 1201 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1202 { 1203 sal_Bool bRet = sal_False; 1204 1205 vos::OGuard aGuard(Application::GetSolarMutex()); 1206 1207 CHECK_FOR_DEFUNC( XAccessibleTable ) 1208 1209 const SwFrm *pFrm = 1210 GetTableData().GetCell( nRow, nColumn, sal_False, this ); 1211 if( pFrm && pFrm->IsCellFrm() ) 1212 { 1213 const SwSelBoxes *pSelBoxes = GetSelBoxes(); 1214 if( pSelBoxes ) 1215 { 1216 const SwCellFrm *pCFrm = static_cast < const SwCellFrm * >( pFrm ); 1217 SwTableBox *pBox = 1218 const_cast< SwTableBox *>( pCFrm->GetTabBox() ); //SVPtrArr! 1219 bRet = pSelBoxes->Seek_Entry( pBox ); 1220 } 1221 } 1222 1223 return bRet; 1224 } 1225 1226 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleIndex( 1227 sal_Int32 nRow, sal_Int32 nColumn ) 1228 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1229 { 1230 sal_Int32 nRet = -1; 1231 1232 vos::OGuard aGuard(Application::GetSolarMutex()); 1233 1234 CHECK_FOR_DEFUNC( XAccessibleTable ) 1235 1236 SwAccessibleChild aCell( GetTableData().GetCell( nRow, nColumn, sal_False, this )); 1237 if ( aCell.IsValid() ) 1238 { 1239 nRet = GetChildIndex( *(GetMap()), aCell ); 1240 } 1241 1242 return nRet; 1243 } 1244 1245 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleRow( sal_Int32 nChildIndex ) 1246 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1247 { 1248 sal_Int32 nRet = -1; 1249 1250 vos::OGuard aGuard(Application::GetSolarMutex()); 1251 1252 CHECK_FOR_DEFUNC( XAccessibleTable ) 1253 1254 // --> OD 2007-06-27 #i77106# 1255 if ( ( nChildIndex < 0 ) || 1256 ( nChildIndex >= getAccessibleChildCount() ) ) 1257 { 1258 throw lang::IndexOutOfBoundsException(); 1259 } 1260 // <-- 1261 1262 SwAccessibleChild aCell( GetChild( *(GetMap()), nChildIndex ) ); 1263 if ( aCell.GetSwFrm() ) 1264 { 1265 sal_Int32 nTop = aCell.GetSwFrm()->Frm().Top(); 1266 nTop -= GetFrm()->Frm().Top(); 1267 Int32Set_Impl::const_iterator aRow( 1268 GetTableData().GetRows().lower_bound( nTop ) ); 1269 nRet = static_cast< sal_Int32 >( ::std::distance( 1270 GetTableData().GetRows().begin(), aRow ) ); 1271 } 1272 else 1273 { 1274 ASSERT( !aCell.IsValid(), "SwAccessibleTable::getAccessibleColumn:" 1275 "aCell not expected to be valid."); 1276 1277 throw lang::IndexOutOfBoundsException(); 1278 } 1279 1280 return nRet; 1281 } 1282 1283 sal_Int32 SAL_CALL SwAccessibleTable::getAccessibleColumn( 1284 sal_Int32 nChildIndex ) 1285 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1286 { 1287 sal_Int32 nRet = -1; 1288 1289 vos::OGuard aGuard(Application::GetSolarMutex()); 1290 1291 CHECK_FOR_DEFUNC( XAccessibleTable ) 1292 1293 // --> OD 2007-06-27 #i77106# 1294 if ( ( nChildIndex < 0 ) || 1295 ( nChildIndex >= getAccessibleChildCount() ) ) 1296 { 1297 throw lang::IndexOutOfBoundsException(); 1298 } 1299 // <-- 1300 1301 SwAccessibleChild aCell( GetChild( *(GetMap()), nChildIndex ) ); 1302 if ( aCell.GetSwFrm() ) 1303 { 1304 sal_Int32 nLeft = aCell.GetSwFrm()->Frm().Left(); 1305 nLeft -= GetFrm()->Frm().Left(); 1306 Int32Set_Impl::const_iterator aCol( 1307 GetTableData().GetColumns().lower_bound( nLeft ) ); 1308 nRet = static_cast< sal_Int32 >( ::std::distance( 1309 GetTableData().GetColumns().begin(), aCol ) ); 1310 } 1311 else 1312 { 1313 ASSERT( !aCell.IsValid(), "SwAccessibleTable::getAccessibleColumn:" 1314 "aCell not expected to be valid."); 1315 1316 throw lang::IndexOutOfBoundsException(); 1317 } 1318 1319 return nRet; 1320 } 1321 1322 1323 OUString SAL_CALL SwAccessibleTable::getImplementationName() 1324 throw( uno::RuntimeException ) 1325 { 1326 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName)); 1327 } 1328 1329 sal_Bool SAL_CALL SwAccessibleTable::supportsService( 1330 const OUString& sTestServiceName) 1331 throw (uno::RuntimeException) 1332 { 1333 return sTestServiceName.equalsAsciiL( sServiceName, 1334 sizeof(sServiceName)-1 ) || 1335 sTestServiceName.equalsAsciiL( sAccessibleServiceName, 1336 sizeof(sAccessibleServiceName)-1 ); 1337 } 1338 1339 uno::Sequence< OUString > SAL_CALL SwAccessibleTable::getSupportedServiceNames() 1340 throw( uno::RuntimeException ) 1341 { 1342 uno::Sequence< OUString > aRet(2); 1343 OUString* pArray = aRet.getArray(); 1344 pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) ); 1345 pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) ); 1346 return aRet; 1347 } 1348 1349 void SwAccessibleTable::InvalidatePosOrSize( const SwRect& rOldBox ) 1350 { 1351 vos::OGuard aGuard(Application::GetSolarMutex()); 1352 1353 if( HasTableData() ) 1354 GetTableData().SetTablePos( GetFrm()->Frm().Pos() ); 1355 1356 SwAccessibleContext::InvalidatePosOrSize( rOldBox ); 1357 } 1358 1359 void SwAccessibleTable::Dispose( sal_Bool bRecursive ) 1360 { 1361 vos::OGuard aGuard(Application::GetSolarMutex()); 1362 1363 if( GetRegisteredIn() ) 1364 GetRegisteredInNonConst()->Remove( this ); 1365 1366 SwAccessibleContext::Dispose( bRecursive ); 1367 } 1368 1369 void SwAccessibleTable::DisposeChild( const SwAccessibleChild& rChildFrmOrObj, 1370 sal_Bool bRecursive ) 1371 { 1372 vos::OGuard aGuard(Application::GetSolarMutex()); 1373 1374 const SwFrm *pFrm = rChildFrmOrObj.GetSwFrm(); 1375 ASSERT( pFrm, "frame expected" ); 1376 if( HasTableData() ) 1377 { 1378 FireTableChangeEvent( GetTableData() ); 1379 ClearTableData(); 1380 } 1381 1382 // There are two reason why this method has been called. The first one 1383 // is there is no context for pFrm. The method is them called by 1384 // the map, and we have to call our superclass. 1385 // The other situation is that we have been call by a call to get notified 1386 // about its change. We then must not call the superclass 1387 uno::Reference< XAccessible > xAcc( GetMap()->GetContext( pFrm, sal_False ) ); 1388 if( !xAcc.is() ) 1389 SwAccessibleContext::DisposeChild( rChildFrmOrObj, bRecursive ); 1390 } 1391 1392 void SwAccessibleTable::InvalidateChildPosOrSize( const SwAccessibleChild& rChildFrmOrObj, 1393 const SwRect& rOldBox ) 1394 { 1395 vos::OGuard aGuard(Application::GetSolarMutex()); 1396 1397 if( HasTableData() ) 1398 { 1399 ASSERT( !HasTableData() || 1400 GetFrm()->Frm().Pos() == GetTableData().GetTablePos(), 1401 "table has invalid position" ); 1402 if( HasTableData() ) 1403 { 1404 // --> OD 2007-06-28 #i77106# 1405 SwAccessibleTableData_Impl *pNewTableData = CreateNewTableData(); 1406 // <-- 1407 if( !pNewTableData->CompareExtents( GetTableData() ) ) 1408 { 1409 FireTableChangeEvent( GetTableData() ); 1410 ClearTableData(); 1411 mpTableData = pNewTableData; 1412 } 1413 else 1414 { 1415 delete pNewTableData; 1416 } 1417 } 1418 } 1419 1420 // --> OD 2010-02-18 #i013961# - always call super class method 1421 SwAccessibleContext::InvalidateChildPosOrSize( rChildFrmOrObj, rOldBox ); 1422 // <-- 1423 } 1424 1425 1426 // 1427 // XAccessibleSelection 1428 // 1429 1430 void SAL_CALL SwAccessibleTable::selectAccessibleChild( 1431 sal_Int32 nChildIndex ) 1432 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException ) 1433 { 1434 vos::OGuard aGuard(Application::GetSolarMutex()); 1435 CHECK_FOR_DEFUNC( XAccessibleTable ); 1436 1437 // --> OD 2007-06-27 #i77106# 1438 if( (nChildIndex < 0) || (nChildIndex >= getAccessibleChildCount()) ) 1439 // <-- 1440 throw lang::IndexOutOfBoundsException(); 1441 1442 // preliminaries: get 'our' table box, and get the cursor shell 1443 const SwTableBox* pBox = GetTableBox( nChildIndex ); 1444 DBG_ASSERT( pBox != NULL, "We need the table box." ); 1445 1446 SwCrsrShell* pCrsrShell = GetCrsrShell(); 1447 if( pCrsrShell == NULL ) 1448 return; 1449 1450 // --> OD 2004-11-16 #111714# - assure, that child, indentified by the given 1451 // index, isn't already selected. 1452 if ( IsChildSelected( nChildIndex ) ) 1453 { 1454 return; 1455 } 1456 // <-- 1457 1458 // now we can start to do the work: check whether we already have 1459 // a table selection (in 'our' table). If so, extend the 1460 // selection, else select the current cell. 1461 1462 // if we have a selection in a table, check if it's in the 1463 // same table that we're trying to select in 1464 const SwTableNode* pSelectedTable = pCrsrShell->IsCrsrInTbl(); 1465 if( pSelectedTable != NULL ) 1466 { 1467 // get top-most table line 1468 const SwTableLine* pUpper = pBox->GetUpper(); 1469 while( pUpper->GetUpper() != NULL ) 1470 pUpper = pUpper->GetUpper()->GetUpper(); 1471 sal_uInt16 nPos = 1472 pSelectedTable->GetTable().GetTabLines().GetPos( pUpper ); 1473 if( nPos == USHRT_MAX ) 1474 pSelectedTable = NULL; 1475 } 1476 1477 // create the new selection 1478 const SwStartNode* pStartNode = pBox->GetSttNd(); 1479 if( pSelectedTable == NULL || !pCrsrShell->GetTblCrs() ) 1480 { 1481 // if we're in the wrong table, or there's no table selection 1482 // at all, then select the current table cell. 1483 // SwPaM* pPaM = pCrsrShell->GetCrsr(); 1484 // pPaM->DeleteMark(); 1485 // *(pPaM->GetPoint()) = SwPosition( *pStartNode ); 1486 // pPaM->Move( fnMoveForward, fnGoNode ); 1487 // // pCrsrShell->SelTblBox(); 1488 1489 pCrsrShell->StartAction(); 1490 // Set cursor into current cell. This deletes any table cursor. 1491 SwPaM aPaM( *pStartNode ); 1492 aPaM.Move( fnMoveForward, fnGoNode ); 1493 Select( aPaM ); 1494 // Move cursor to the end of the table creating a selection and a table 1495 // cursor. 1496 pCrsrShell->SetMark(); 1497 pCrsrShell->MoveTable( fnTableCurr, fnTableEnd ); 1498 // now set the cursor into the cell again. 1499 SwPaM *pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs() 1500 : pCrsrShell->GetCrsr(); 1501 *pPaM->GetPoint() = *pPaM->GetMark(); 1502 pCrsrShell->EndAction(); 1503 // we now have one cell selected! 1504 } 1505 else 1506 { 1507 // if the cursor is already in this table, 1508 // expand the current selection (i.e., set 1509 // point to new position; keep mark) 1510 SwPaM aPaM( *pStartNode ); 1511 aPaM.Move( fnMoveForward, fnGoNode ); 1512 aPaM.SetMark(); 1513 const SwPaM *pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs() 1514 : pCrsrShell->GetCrsr(); 1515 *(aPaM.GetMark()) = *pPaM->GetMark(); 1516 Select( aPaM ); 1517 1518 // if only one box is selected, we select this one in 1519 // order to maintain our table selection 1520 // if( aPaM.GetPoint()->nNode.GetNode().FindTableBoxStartNode() == 1521 // aPaM.GetMark()->nNode.GetNode().FindTableBoxStartNode() ) 1522 // { 1523 // // pCrsrShell->SelTblBox(); 1524 // } 1525 // else 1526 // { 1527 // finally; set the selection. This will call UpdateCursor 1528 // on the cursor shell, too. 1529 // pCrsrShell->KillPams(); 1530 // pCrsrShell->SetSelection( aPaM ); 1531 // } 1532 } 1533 } 1534 1535 1536 sal_Bool SAL_CALL SwAccessibleTable::isAccessibleChildSelected( 1537 sal_Int32 nChildIndex ) 1538 throw ( lang::IndexOutOfBoundsException, 1539 uno::RuntimeException ) 1540 { 1541 vos::OGuard aGuard(Application::GetSolarMutex()); 1542 CHECK_FOR_DEFUNC( XAccessibleTable ); 1543 1544 // --> OD 2007-06-27 #i77106# 1545 if( (nChildIndex < 0) || (nChildIndex >= getAccessibleChildCount()) ) 1546 // <-- 1547 throw lang::IndexOutOfBoundsException(); 1548 1549 return IsChildSelected( nChildIndex ); 1550 } 1551 1552 void SAL_CALL SwAccessibleTable::clearAccessibleSelection( ) 1553 throw ( uno::RuntimeException ) 1554 { 1555 vos::OGuard aGuard(Application::GetSolarMutex()); 1556 1557 CHECK_FOR_DEFUNC( XAccessibleTable ); 1558 1559 SwCrsrShell* pCrsrShell = GetCrsrShell(); 1560 if( pCrsrShell != NULL ) 1561 { 1562 pCrsrShell->StartAction(); 1563 pCrsrShell->ClearMark(); 1564 pCrsrShell->EndAction(); 1565 } 1566 } 1567 1568 void SAL_CALL SwAccessibleTable::selectAllAccessibleChildren( ) 1569 throw ( uno::RuntimeException ) 1570 { 1571 // first clear selection, then select first and last child 1572 clearAccessibleSelection(); 1573 selectAccessibleChild( 0 ); 1574 // --> OD 2007-06-27 #i77106# 1575 selectAccessibleChild( getAccessibleChildCount()-1 ); 1576 // <-- 1577 } 1578 1579 sal_Int32 SAL_CALL SwAccessibleTable::getSelectedAccessibleChildCount( ) 1580 throw ( uno::RuntimeException ) 1581 { 1582 vos::OGuard aGuard(Application::GetSolarMutex()); 1583 CHECK_FOR_DEFUNC( XAccessibleTable ); 1584 1585 // iterate over all children and count isAccessibleChildSelected() 1586 sal_Int32 nCount = 0; 1587 1588 // --> OD 2007-06-27 #i71106# 1589 sal_Int32 nChildren = getAccessibleChildCount(); 1590 // <-- 1591 for( sal_Int32 n = 0; n < nChildren; n++ ) 1592 if( IsChildSelected( n ) ) 1593 nCount++; 1594 1595 return nCount; 1596 } 1597 1598 uno::Reference<XAccessible> SAL_CALL SwAccessibleTable::getSelectedAccessibleChild( 1599 sal_Int32 nSelectedChildIndex ) 1600 throw ( lang::IndexOutOfBoundsException, 1601 uno::RuntimeException) 1602 { 1603 vos::OGuard aGuard(Application::GetSolarMutex()); 1604 CHECK_FOR_DEFUNC( XAccessibleTable ); 1605 1606 // paremter checking (part 1): index lower 0 1607 if( nSelectedChildIndex < 0 ) 1608 throw lang::IndexOutOfBoundsException(); 1609 1610 sal_Int32 nChildIndex = GetIndexOfSelectedChild( nSelectedChildIndex ); 1611 1612 // parameter checking (part 2): index higher than selected children? 1613 if( nChildIndex < 0 ) 1614 throw lang::IndexOutOfBoundsException(); 1615 1616 // --> OD 2007-06-28 #i77106# 1617 if ( nChildIndex >= getAccessibleChildCount() ) 1618 { 1619 throw lang::IndexOutOfBoundsException(); 1620 } 1621 // <-- 1622 1623 return getAccessibleChild( nChildIndex ); 1624 } 1625 1626 // --> OD 2004-11-16 #111714# - index has to be treated as global child index. 1627 void SAL_CALL SwAccessibleTable::deselectAccessibleChild( 1628 sal_Int32 nChildIndex ) 1629 throw ( lang::IndexOutOfBoundsException, 1630 uno::RuntimeException ) 1631 { 1632 vos::OGuard aGuard(Application::GetSolarMutex()); 1633 CHECK_FOR_DEFUNC( XAccessibleTable ); 1634 1635 SwCrsrShell* pCrsrShell = GetCrsrShell(); 1636 1637 // --> OD 2004-11-16 #111714# - index has to be treated as global child index 1638 if ( !pCrsrShell ) 1639 throw lang::IndexOutOfBoundsException(); 1640 1641 // assure, that given child index is in bounds. 1642 // --> OD 2007-06-27 #i77106# 1643 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) 1644 // <-- 1645 throw lang::IndexOutOfBoundsException(); 1646 1647 // assure, that child, identified by the given index, is selected. 1648 if ( !IsChildSelected( nChildIndex ) ) 1649 return; 1650 // <-- 1651 1652 const SwTableBox* pBox = GetTableBox( nChildIndex ); 1653 DBG_ASSERT( pBox != NULL, "We need the table box." ); 1654 1655 // If we unselect point, then set cursor to mark. If we clear another 1656 // selected box, then set cursor to point. 1657 // reduce selection to mark. 1658 SwPaM *pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs() 1659 : pCrsrShell->GetCrsr(); 1660 sal_Bool bDeselectPoint = 1661 pBox->GetSttNd() == 1662 pPaM->GetPoint()->nNode.GetNode().FindTableBoxStartNode(); 1663 1664 SwPaM aPaM( bDeselectPoint ? *pPaM->GetMark() : *pPaM->GetPoint() ); 1665 1666 pCrsrShell->StartAction(); 1667 1668 // Set cursor into either point or mark 1669 Select( aPaM ); 1670 // Move cursor to the end of the table creating a selection and a table 1671 // cursor. 1672 pCrsrShell->SetMark(); 1673 pCrsrShell->MoveTable( fnTableCurr, fnTableEnd ); 1674 // now set the cursor into the cell again. 1675 pPaM = pCrsrShell->GetTblCrs() ? pCrsrShell->GetTblCrs() 1676 : pCrsrShell->GetCrsr(); 1677 *pPaM->GetPoint() = *pPaM->GetMark(); 1678 pCrsrShell->EndAction(); 1679 } 1680 1681 // --> OD 2007-06-28 #i77106# 1682 // implementation of class <SwAccessibleTableColHeaders> 1683 SwAccessibleTableColHeaders::SwAccessibleTableColHeaders( SwAccessibleMap *pMap2, 1684 const SwTabFrm *pTabFrm ) 1685 : SwAccessibleTable( pMap2, pTabFrm ) 1686 { 1687 vos::OGuard aGuard(Application::GetSolarMutex()); 1688 1689 const SwFrmFmt *pFrmFmt = pTabFrm->GetFmt(); 1690 const_cast< SwFrmFmt * >( pFrmFmt )->Add( this ); 1691 const String& rName = pFrmFmt->GetName(); 1692 1693 OUStringBuffer aBuffer( rName.Len() + 15 + 6 ); 1694 aBuffer.append( OUString(rName) ); 1695 aBuffer.append( String::CreateFromAscii("-ColumnHeaders-") ); 1696 aBuffer.append( static_cast<sal_Int32>( pTabFrm->GetPhyPageNum() ) ); 1697 1698 SetName( aBuffer.makeStringAndClear() ); 1699 1700 OUStringBuffer aBuffer2( rName.Len() + 14 ); 1701 aBuffer2.append( OUString(rName) ); 1702 aBuffer2.append( String::CreateFromAscii("-ColumnHeaders") ); 1703 OUString sArg1( aBuffer2.makeStringAndClear() ); 1704 OUString sArg2( GetFormattedPageNumber() ); 1705 1706 OUString sDesc2 = GetResource( STR_ACCESS_TABLE_DESC, &sArg1, &sArg2 ); 1707 SetDesc( sDesc2 ); 1708 1709 // --> OD 2008-03-10 #i85634# 1710 NotRegisteredAtAccessibleMap(); 1711 // <-- 1712 } 1713 1714 SwAccessibleTableData_Impl* SwAccessibleTableColHeaders::CreateNewTableData() 1715 { 1716 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( GetFrm() ); 1717 return new SwAccessibleTableData_Impl( *(GetMap()), pTabFrm, IsInPagePreview(), true ); 1718 } 1719 1720 1721 void SwAccessibleTableColHeaders::Modify( const SfxPoolItem * /*pOld*/, const SfxPoolItem * /*pNew*/ ) 1722 { 1723 } 1724 1725 //===== XInterface ====================================================== 1726 uno::Any SAL_CALL SwAccessibleTableColHeaders::queryInterface( const uno::Type& aType ) 1727 throw (uno::RuntimeException) 1728 { 1729 return SwAccessibleTable::queryInterface( aType ); 1730 } 1731 1732 //===== XAccessibleContext ============================================== 1733 sal_Int32 SAL_CALL SwAccessibleTableColHeaders::getAccessibleChildCount(void) 1734 throw (uno::RuntimeException) 1735 { 1736 vos::OGuard aGuard(Application::GetSolarMutex()); 1737 1738 CHECK_FOR_DEFUNC( XAccessibleContext ) 1739 1740 sal_Int32 nCount = 0; 1741 1742 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( GetFrm() ); 1743 const SwAccessibleChildSList aVisList( GetVisArea(), *pTabFrm, *(GetMap()) ); 1744 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); 1745 while( aIter != aVisList.end() ) 1746 { 1747 const SwAccessibleChild& rLower = *aIter; 1748 if( rLower.IsAccessible( IsInPagePreview() ) ) 1749 { 1750 nCount++; 1751 } 1752 else if( rLower.GetSwFrm() ) 1753 { 1754 // There are no unaccessible SdrObjects that count 1755 if ( !rLower.GetSwFrm()->IsRowFrm() || 1756 pTabFrm->IsInHeadline( *(rLower.GetSwFrm()) ) ) 1757 { 1758 nCount += SwAccessibleFrame::GetChildCount( *(GetMap()), 1759 GetVisArea(), 1760 rLower.GetSwFrm(), 1761 IsInPagePreview() ); 1762 } 1763 } 1764 ++aIter; 1765 } 1766 1767 return nCount; 1768 } 1769 1770 uno::Reference< XAccessible> SAL_CALL 1771 SwAccessibleTableColHeaders::getAccessibleChild (sal_Int32 nIndex) 1772 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 1773 { 1774 if ( nIndex < 0 || nIndex >= getAccessibleChildCount() ) 1775 { 1776 throw lang::IndexOutOfBoundsException(); 1777 } 1778 1779 return SwAccessibleTable::getAccessibleChild( nIndex ); 1780 } 1781 1782 //===== XAccessibleTable ================================================ 1783 uno::Reference< XAccessibleTable > 1784 SAL_CALL SwAccessibleTableColHeaders::getAccessibleRowHeaders() 1785 throw (uno::RuntimeException) 1786 { 1787 return uno::Reference< XAccessibleTable >(); 1788 } 1789 1790 uno::Reference< XAccessibleTable > 1791 SAL_CALL SwAccessibleTableColHeaders::getAccessibleColumnHeaders() 1792 throw (uno::RuntimeException) 1793 { 1794 return uno::Reference< XAccessibleTable >(); 1795 } 1796 1797 //===== XServiceInfo ==================================================== 1798 1799 ::rtl::OUString SAL_CALL SwAccessibleTableColHeaders::getImplementationName (void) 1800 throw (uno::RuntimeException) 1801 { 1802 static const sal_Char sImplName[] = "com.sun.star.comp.Writer.SwAccessibleTableColumnHeadersView"; 1803 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplName)); 1804 } 1805