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