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