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