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