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