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_sc.hxx" 26 27 28 #include "AccessibleSpreadsheet.hxx" 29 #include "AccessibilityHints.hxx" 30 #include "AccessibleCell.hxx" 31 #include "AccessibleDocument.hxx" 32 #include "tabvwsh.hxx" 33 #include "document.hxx" 34 #include "unoguard.hxx" 35 #include "hints.hxx" 36 #include "scmod.hxx" 37 38 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX 39 #include <unotools/accessiblestatesethelper.hxx> 40 #endif 41 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_ 42 #include <com/sun/star/accessibility/AccessibleRole.hpp> 43 #endif 44 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_ 45 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 46 #endif 47 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 48 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> 49 #include <rtl/uuid.h> 50 #include <tools/debug.hxx> 51 #include <tools/gen.hxx> 52 #include <svtools/colorcfg.hxx> 53 #include "scresid.hxx" 54 #include "sc.hrc" 55 #include <algorithm> 56 57 using namespace ::com::sun::star; 58 using namespace ::com::sun::star::accessibility; 59 60 bool CompMinCol(const std::pair<sal_uInt16,sal_uInt16> & pc1,const std::pair<sal_uInt16,sal_uInt16> &pc2) 61 { 62 return pc1.first < pc2.first; 63 } 64 ScMyAddress ScAccessibleSpreadsheet::CalcScAddressFromRangeList(ScRangeList *pMarkedRanges,sal_Int32 nSelectedChildIndex) 65 { 66 if (pMarkedRanges->Count() <= 1) 67 { 68 ScRange* pRange = pMarkedRanges->First(); 69 if (pRange) 70 { 71 // MT IA2: Not used. 72 // const int nRowNum = pRange->aEnd.Row() - pRange->aStart.Row() + 1; 73 const int nColNum = pRange->aEnd.Col() - pRange->aStart.Col() + 1; 74 const int nCurCol = nSelectedChildIndex % nColNum; 75 const int nCurRow = (nSelectedChildIndex - nCurCol)/nColNum; 76 return ScMyAddress(static_cast<SCCOL>(pRange->aStart.Col() + nCurCol), pRange->aStart.Row() + nCurRow, maActiveCell.Tab()); 77 } 78 } 79 else 80 { 81 sal_Int32 nMinRow = MAXROW; 82 sal_Int32 nMaxRow = 0; 83 m_vecTempRange.clear(); 84 ScRange* pRange = pMarkedRanges->First(); 85 while (pRange) 86 { 87 if (pRange->aStart.Tab() != pRange->aEnd.Tab()) 88 { 89 if ((maActiveCell.Tab() >= pRange->aStart.Tab()) || 90 maActiveCell.Tab() <= pRange->aEnd.Tab()) 91 { 92 m_vecTempRange.push_back(pRange); 93 nMinRow = std::min(pRange->aStart.Row(),nMinRow); 94 nMaxRow = std::max(pRange->aEnd.Row(),nMaxRow); 95 } 96 else 97 DBG_ERROR("Range of wrong table"); 98 } 99 else if(pRange->aStart.Tab() == maActiveCell.Tab()) 100 { 101 m_vecTempRange.push_back(pRange); 102 nMinRow = std::min(pRange->aStart.Row(),nMinRow); 103 nMaxRow = std::max(pRange->aEnd.Row(),nMaxRow); 104 } 105 else 106 DBG_ERROR("Range of wrong table"); 107 pRange = pMarkedRanges->Next(); 108 } 109 int nCurrentIndex = 0 ; 110 for(sal_Int32 row = nMinRow ; row <= nMaxRow ; ++row) 111 { 112 m_vecTempCol.clear(); 113 { 114 VEC_RANGE::const_iterator vi = m_vecTempRange.begin(); 115 for (; vi < m_vecTempRange.end(); ++vi) 116 { 117 ScRange *p = *vi; 118 if ( row >= p->aStart.Row() && row <= p->aEnd.Row()) 119 { 120 m_vecTempCol.push_back(std::make_pair(p->aStart.Col(),p->aEnd.Col())); 121 } 122 } 123 } 124 std::sort(m_vecTempCol.begin(),m_vecTempCol.end(),CompMinCol); 125 { 126 VEC_COL::const_iterator vic = m_vecTempCol.begin(); 127 for(; vic != m_vecTempCol.end(); ++vic) 128 { 129 const PAIR_COL &pariCol = *vic; 130 sal_uInt16 nCol = pariCol.second - pariCol.first + 1; 131 if (nCol + nCurrentIndex > nSelectedChildIndex) 132 { 133 return ScMyAddress(static_cast<SCCOL>(pariCol.first + nSelectedChildIndex - nCurrentIndex), row, maActiveCell.Tab()); 134 } 135 nCurrentIndex += nCol; 136 } 137 } 138 } 139 } 140 return ScMyAddress(0,0,maActiveCell.Tab()); 141 } 142 sal_Bool ScAccessibleSpreadsheet::CalcScRangeDifferenceMax(ScRange *pSrc,ScRange *pDest,int nMax,VEC_MYADDR &vecRet,int &nSize) 143 { 144 //Src Must be :Src > Dest 145 if (pDest->In(*pSrc)) 146 {//Here is Src In Dest,Src <= Dest 147 return sal_False; 148 } 149 if (!pDest->Intersects(*pSrc)) 150 { 151 int nCellCount = sal_uInt32(pDest->aEnd.Col() - pDest->aStart.Col() + 1) 152 * sal_uInt32(pDest->aEnd.Row() - pDest->aStart.Row() + 1) 153 * sal_uInt32(pDest->aEnd.Tab() - pDest->aStart.Tab() + 1); 154 if (nCellCount + nSize > nMax) 155 { 156 return sal_True; 157 } 158 else if(nCellCount > 0) 159 { 160 nCellCount +=nSize; 161 for (sal_Int32 row = pDest->aStart.Row(); row <= pDest->aEnd.Row();++row) 162 { 163 for (sal_uInt16 col = pDest->aStart.Col(); col <= pDest->aEnd.Col();++col) 164 { 165 vecRet.push_back(ScMyAddress(col,row,pDest->aStart.Tab())); 166 } 167 } 168 } 169 return sal_False; 170 } 171 sal_Int32 nMinRow = pSrc->aStart.Row(); 172 sal_Int32 nMaxRow = pSrc->aEnd.Row(); 173 for (; nMinRow <= nMaxRow ; ++nMinRow,--nMaxRow) 174 { 175 for (sal_uInt16 col = pSrc->aStart.Col(); col <= pSrc->aEnd.Col();++col) 176 { 177 if (nSize > nMax) 178 { 179 return sal_True; 180 } 181 ScMyAddress cell(col,nMinRow,pSrc->aStart.Tab()); 182 if(!pDest->In(cell)) 183 {//In Src ,Not In Dest 184 vecRet.push_back(cell); 185 ++nSize; 186 } 187 } 188 if (nMinRow != nMaxRow) 189 { 190 for (sal_uInt16 col = pSrc->aStart.Col(); col <= pSrc->aEnd.Col();++col) 191 { 192 if (nSize > nMax) 193 { 194 return sal_True; 195 } 196 ScMyAddress cell(col,nMaxRow,pSrc->aStart.Tab()); 197 if(!pDest->In(cell)) 198 {//In Src ,Not In Dest 199 vecRet.push_back(cell); 200 ++nSize; 201 } 202 } 203 } 204 } 205 return sal_False; 206 } 207 //In Src , Not in Dest 208 sal_Bool ScAccessibleSpreadsheet::CalcScRangeListDifferenceMax(ScRangeList *pSrc,ScRangeList *pDest,int nMax,VEC_MYADDR &vecRet) 209 { 210 if (pSrc == NULL || pDest == NULL) 211 { 212 return sal_False; 213 } 214 int nSize =0; 215 if (pDest->GetCellCount() == 0)//if the Dest Rang List is empty 216 { 217 if (pSrc->GetCellCount() > sal_uInt32(nMax))//if the Src Cell count is greater then nMax 218 { 219 return sal_True; 220 } 221 //now the cell count is less then nMax 222 vecRet.reserve(10); 223 ScRange* pRange = pSrc->First(); 224 while (pRange) 225 { 226 for (sal_Int32 row = pRange->aStart.Row(); row <= pRange->aEnd.Row();++row) 227 { 228 for (sal_uInt16 col = pRange->aStart.Col(); col <= pRange->aEnd.Col();++col) 229 { 230 vecRet.push_back(ScMyAddress(col,row,pRange->aStart.Tab())); 231 } 232 } 233 pRange = pSrc->Next(); 234 } 235 return sal_False; 236 } 237 //the Dest Rang List is not empty 238 vecRet.reserve(10); 239 ScRange* pRange = pSrc->First(); 240 while (pRange) 241 { 242 ScRange* pRangeDest = pDest->First(); 243 while (pRangeDest) 244 { 245 if (CalcScRangeDifferenceMax(pRange,pRangeDest,nMax,vecRet,nSize)) 246 { 247 return sal_True; 248 } 249 pRangeDest = pDest->Next(); 250 } 251 pRange = pSrc->Next(); 252 } 253 return sal_False; 254 } 255 //===== internal ============================================================ 256 257 ScAccessibleSpreadsheet::ScAccessibleSpreadsheet( 258 ScAccessibleDocument* pAccDoc, 259 ScTabViewShell* pViewShell, 260 SCTAB nTab, 261 ScSplitPos eSplitPos) 262 : 263 ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell), 264 ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))), 265 mbIsSpreadsheet( sal_True ), 266 m_bFormulaMode(sal_False), 267 m_bFormulaLastMode(sal_False), 268 m_pAccFormulaCell(NULL), 269 m_nMinX(0),m_nMaxX(0),m_nMinY(0),m_nMaxY(0) 270 { 271 ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos ); 272 } 273 274 ScAccessibleSpreadsheet::ScAccessibleSpreadsheet( 275 ScAccessibleSpreadsheet& rParent, const ScRange& rRange ) : 276 ScAccessibleTableBase( rParent.mpAccDoc, rParent.mpDoc, rRange), 277 mbIsSpreadsheet( sal_False ) 278 { 279 ConstructScAccessibleSpreadsheet( rParent.mpAccDoc, rParent.mpViewShell, rParent.mnTab, rParent.meSplitPos ); 280 } 281 282 ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet() 283 { 284 if (mpMarkedRanges) 285 delete mpMarkedRanges; 286 if (mpViewShell) 287 mpViewShell->RemoveAccessibilityObject(*this); 288 } 289 290 void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet( 291 ScAccessibleDocument* pAccDoc, 292 ScTabViewShell* pViewShell, 293 SCTAB nTab, 294 ScSplitPos eSplitPos) 295 { 296 mpViewShell = pViewShell; 297 mpMarkedRanges = 0; 298 mpSortedMarkedCells = 0; 299 mpAccDoc = pAccDoc; 300 mpAccCell = 0; 301 meSplitPos = eSplitPos; 302 mnTab = nTab; 303 mbHasSelection = sal_False; 304 mbDelIns = sal_False; 305 mbIsFocusSend = sal_False; 306 maVisCells = GetVisCells(GetVisArea(mpViewShell, meSplitPos)); 307 if (mpViewShell) 308 { 309 mpViewShell->AddAccessibilityObject(*this); 310 311 const ScViewData& rViewData = *mpViewShell->GetViewData(); 312 const ScMarkData& rMarkData = rViewData.GetMarkData(); 313 maActiveCell = rViewData.GetCurPos(); 314 mbHasSelection = rMarkData.GetTableSelect(maActiveCell.Tab()) && 315 (rMarkData.IsMarked() || rMarkData.IsMultiMarked()); 316 mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col()); 317 mpAccCell->acquire(); 318 mpAccCell->Init(); 319 ScDocument* pScDoc= GetDocument(mpViewShell); 320 if (pScDoc) 321 { 322 pScDoc->GetName( maActiveCell.Tab(), m_strOldTabName ); 323 } 324 } 325 } 326 327 void SAL_CALL ScAccessibleSpreadsheet::disposing() 328 { 329 ScUnoGuard aGuard; 330 if (mpViewShell) 331 { 332 mpViewShell->RemoveAccessibilityObject(*this); 333 mpViewShell = NULL; 334 } 335 if (mpAccCell) 336 { 337 mpAccCell->release(); 338 mpAccCell = NULL; 339 } 340 341 ScAccessibleTableBase::disposing(); 342 } 343 344 void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState) 345 { 346 if (IsFormulaMode()) 347 { 348 return ; 349 } 350 if (mpMarkedRanges) 351 DELETEZ(mpMarkedRanges); 352 mbHasSelection = bNewState; 353 354 AccessibleEventObject aEvent; 355 aEvent.EventId = AccessibleEventId::STATE_CHANGED; 356 if (bNewState) 357 aEvent.NewValue = uno::makeAny(AccessibleStateType::SELECTED); 358 else 359 aEvent.OldValue = uno::makeAny(AccessibleStateType::SELECTED); 360 aEvent.Source = uno::Reference< XAccessibleContext >(this); 361 362 CommitChange(aEvent); 363 } 364 365 void ScAccessibleSpreadsheet::LostFocus() 366 { 367 AccessibleEventObject aEvent; 368 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 369 aEvent.Source = uno::Reference< XAccessibleContext >(this); 370 uno::Reference< XAccessible > xOld = mpAccCell; 371 aEvent.OldValue <<= xOld; 372 373 CommitChange(aEvent); 374 375 CommitFocusLost(); 376 } 377 378 void ScAccessibleSpreadsheet::GotFocus() 379 { 380 AccessibleEventObject aEvent; 381 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 382 aEvent.Source = uno::Reference< XAccessibleContext >(this); 383 uno::Reference< XAccessible > xNew; 384 if (IsFormulaMode()) 385 { 386 if (!m_pAccFormulaCell || !m_bFormulaLastMode) 387 { 388 ScAddress aFormulaAddr; 389 if(!GetFormulaCurrentFocusCell(aFormulaAddr)) 390 { 391 return; 392 } 393 m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(),aFormulaAddr.Col()); 394 395 m_pAccFormulaCell->acquire(); 396 m_pAccFormulaCell->Init(); 397 398 399 } 400 xNew = m_pAccFormulaCell; 401 } 402 else 403 { 404 if(mpAccCell->GetCellAddress() == maActiveCell) 405 { 406 xNew = mpAccCell; 407 } 408 else 409 { 410 CommitFocusCell(maActiveCell); 411 return ; 412 } 413 } 414 aEvent.NewValue <<= xNew; 415 416 CommitChange(aEvent); 417 } 418 419 void ScAccessibleSpreadsheet::BoundingBoxChanged() 420 { 421 AccessibleEventObject aEvent; 422 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED; 423 aEvent.Source = uno::Reference< XAccessibleContext >(this); 424 425 CommitChange(aEvent); 426 } 427 428 void ScAccessibleSpreadsheet::VisAreaChanged() 429 { 430 AccessibleEventObject aEvent; 431 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED; 432 aEvent.Source = uno::Reference< XAccessibleContext >(this); 433 434 CommitChange(aEvent); 435 } 436 437 //===== SfxListener ===================================================== 438 439 void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 440 { 441 if (rHint.ISA( SfxSimpleHint ) ) 442 { 443 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint; 444 if ((rRef.GetId() == SC_HINT_ACC_CURSORCHANGED)) 445 { 446 if (mpViewShell) 447 { 448 ScViewData *pViewData = mpViewShell->GetViewData(); 449 450 m_bFormulaMode = pViewData->IsRefMode() || SC_MOD()->IsFormulaMode(); 451 if ( m_bFormulaMode ) 452 { 453 NotifyRefMode(); 454 m_bFormulaLastMode = true; 455 return ; 456 } 457 if (m_bFormulaLastMode) 458 {//Last Notify Mode Is Formula Mode. 459 m_vecFormulaLastMyAddr.clear(); 460 RemoveFormulaSelection(sal_True); 461 if(m_pAccFormulaCell) 462 { 463 m_pAccFormulaCell->release(); 464 m_pAccFormulaCell =NULL; 465 } 466 //Remove All Selection 467 } 468 m_bFormulaLastMode = m_bFormulaMode; 469 470 AccessibleEventObject aEvent; 471 aEvent.Source = uno::Reference< XAccessible >(this); 472 ScAddress aNewCell = pViewData->GetCurPos(); 473 if(aNewCell.Tab() != maActiveCell.Tab()) 474 { 475 aEvent.EventId = AccessibleEventId::PAGE_CHANGED; 476 ScAccessibleDocument *pAccDoc = 477 static_cast<ScAccessibleDocument*>(getAccessibleParent().get()); 478 if(pAccDoc) 479 { 480 pAccDoc->CommitChange(aEvent); 481 } 482 } 483 sal_Bool bNewPosCell = (aNewCell != maActiveCell); 484 sal_Bool bNewPosCellFocus=sal_False; 485 if ( bNewPosCell && IsFocused() && aNewCell.Tab() == maActiveCell.Tab() ) 486 {//single Focus 487 bNewPosCellFocus=sal_True; 488 } 489 ScMarkData &refScMarkData = pViewData->GetMarkData(); 490 // MT IA2: Not used 491 // int nSelCount = refScMarkData.GetSelectCount(); 492 sal_Bool bIsMark =refScMarkData.IsMarked(); 493 sal_Bool bIsMultMark = refScMarkData.IsMultiMarked(); 494 sal_Bool bNewMarked = refScMarkData.GetTableSelect(aNewCell.Tab()) && ( bIsMark || bIsMultMark ); 495 // sal_Bool bNewCellSelected = isAccessibleSelected(aNewCell.Row(), aNewCell.Col()); 496 sal_uInt16 nTab = pViewData->GetTabNo(); 497 ScRange aMarkRange; 498 refScMarkData.GetMarkArea(aMarkRange); 499 aEvent.OldValue <<= ::com::sun::star::uno::Any(); 500 //Mark All 501 if ( !bNewPosCellFocus && 502 (bNewMarked || bIsMark || bIsMultMark ) && 503 aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) ) 504 { 505 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 506 aEvent.NewValue <<= ::com::sun::star::uno::Any(); 507 CommitChange(aEvent); 508 return ; 509 } 510 if (!mpMarkedRanges) 511 { 512 mpMarkedRanges = new ScRangeList(); 513 } 514 refScMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_True); 515 516 //For Whole Col Row 517 sal_Bool bWholeRow = ::labs(aMarkRange.aStart.Row() - aMarkRange.aEnd.Row()) == MAXROW ; 518 sal_Bool bWholeCol = ::abs(aMarkRange.aStart.Col() - aMarkRange.aEnd.Col()) == MAXCOL ; 519 if ((bNewMarked || bIsMark || bIsMultMark ) && (bWholeCol || bWholeRow)) 520 { 521 if ( aMarkRange != m_aLastWithInMarkRange ) 522 { 523 RemoveSelection(refScMarkData); 524 if(bNewPosCell) 525 { 526 CommitFocusCell(aNewCell); 527 } 528 sal_Bool bLastIsWholeColRow = 529 ::labs(m_aLastWithInMarkRange.aStart.Row() - m_aLastWithInMarkRange.aEnd.Row()) == MAXROW && bWholeRow || 530 ::abs(m_aLastWithInMarkRange.aStart.Col() - m_aLastWithInMarkRange.aEnd.Col()) == MAXCOL && bWholeCol ; 531 sal_Bool bSelSmaller= 532 bLastIsWholeColRow && 533 !aMarkRange.In(m_aLastWithInMarkRange) && 534 aMarkRange.Intersects(m_aLastWithInMarkRange); 535 if( !bSelSmaller ) 536 { 537 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 538 aEvent.NewValue <<= ::com::sun::star::uno::Any(); 539 CommitChange(aEvent); 540 } 541 m_aLastWithInMarkRange = aMarkRange; 542 } 543 return ; 544 } 545 m_aLastWithInMarkRange = aMarkRange; 546 int nNewMarkCount = mpMarkedRanges->GetCellCount(); 547 sal_Bool bSendSingle= (0 == nNewMarkCount) && bNewPosCell; 548 if (bSendSingle) 549 { 550 RemoveSelection(refScMarkData); 551 if(bNewPosCellFocus) 552 { 553 CommitFocusCell(aNewCell); 554 } 555 uno::Reference< XAccessible > xChild ; 556 if (bNewPosCellFocus) 557 { 558 xChild = mpAccCell; 559 } 560 else 561 { 562 xChild = getAccessibleCellAt(aNewCell.Row(),aNewCell.Col()); 563 564 maActiveCell = aNewCell; 565 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS; 566 aEvent.NewValue <<= xChild; 567 aEvent.OldValue <<= uno::Reference< XAccessible >(); 568 CommitChange(aEvent); 569 } 570 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 571 aEvent.NewValue <<= xChild; 572 CommitChange(aEvent); 573 OSL_ASSERT(m_mapSelectionSend.count(aNewCell) == 0 ); 574 m_mapSelectionSend.insert(MAP_ADDR_XACC::value_type(aNewCell,xChild)); 575 576 } 577 else 578 { 579 ScRange aDelRange; 580 sal_Bool bIsDel = pViewData->GetDelMark( aDelRange ); 581 if ( (!bIsDel || (bIsDel && aMarkRange != aDelRange)) && 582 bNewMarked && 583 nNewMarkCount > 0 && 584 !IsSameMarkCell() ) 585 { 586 RemoveSelection(refScMarkData); 587 if(bNewPosCellFocus) 588 { 589 CommitFocusCell(aNewCell); 590 } 591 VEC_MYADDR vecNew; 592 if(CalcScRangeListDifferenceMax(mpMarkedRanges,&m_LastMarkedRanges,10,vecNew)) 593 { 594 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 595 aEvent.NewValue <<= ::com::sun::star::uno::Any(); 596 CommitChange(aEvent); 597 } 598 else 599 { 600 VEC_MYADDR::iterator viAddr = vecNew.begin(); 601 for(; viAddr < vecNew.end() ; ++viAddr ) 602 { 603 uno::Reference< XAccessible > xChild = getAccessibleCellAt(viAddr->Row(),viAddr->Col()); 604 if (!(bNewPosCellFocus && *viAddr == aNewCell) ) 605 { 606 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS; 607 aEvent.NewValue <<= xChild; 608 CommitChange(aEvent); 609 } 610 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; 611 aEvent.NewValue <<= xChild; 612 CommitChange(aEvent); 613 m_mapSelectionSend.insert(MAP_ADDR_XACC::value_type(*viAddr,xChild)); 614 } 615 } 616 } 617 } 618 if (bNewPosCellFocus && maActiveCell != aNewCell) 619 { 620 CommitFocusCell(aNewCell); 621 } 622 m_LastMarkedRanges = *mpMarkedRanges; 623 } 624 } 625 else if ((rRef.GetId() == SC_HINT_DATACHANGED)) 626 { 627 if (!mbDelIns) 628 CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE); 629 else 630 mbDelIns = sal_False; 631 ScViewData *pViewData = mpViewShell->GetViewData(); 632 ScAddress aNewCell = pViewData->GetCurPos(); 633 if( maActiveCell == aNewCell) 634 { 635 ScDocument* pScDoc= GetDocument(mpViewShell); 636 if (pScDoc) 637 { 638 String valStr; 639 pScDoc->GetString(aNewCell.Col(),aNewCell.Row(),aNewCell.Tab(), valStr); 640 if(m_strCurCellValue != valStr) 641 { 642 AccessibleEventObject aEvent; 643 aEvent.EventId = AccessibleEventId::VALUE_CHANGED; 644 mpAccCell->CommitChange(aEvent); 645 m_strCurCellValue=valStr; 646 } 647 String tabName; 648 pScDoc->GetName( maActiveCell.Tab(), tabName ); 649 if( m_strOldTabName != tabName ) 650 { 651 AccessibleEventObject aEvent; 652 aEvent.EventId = AccessibleEventId::NAME_CHANGED; 653 String sOldName(ScResId(STR_ACC_TABLE_NAME)); 654 sOldName.SearchAndReplaceAscii("%1", m_strOldTabName); 655 aEvent.OldValue <<= ::rtl::OUString( sOldName ); 656 String sNewName(ScResId(STR_ACC_TABLE_NAME)); 657 sNewName.SearchAndReplaceAscii("%1", tabName); 658 aEvent.NewValue <<= ::rtl::OUString( sNewName ); 659 CommitChange( aEvent ); 660 m_strOldTabName = tabName; 661 } 662 } 663 } 664 } 665 // no longer needed, because the document calls the VisAreaChanged method 666 /* else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) 667 { 668 AccessibleEventObject aEvent; 669 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED; 670 aEvent.Source = uno::Reference< XAccessibleContext >(this); 671 672 CommitChange(aEvent);*/ 673 // commented out, because to use a ModelChangeEvent is not the right way 674 // at the moment there is no way, but the Java/Gnome Api should be extended sometime 675 /* if (mpViewShell) 676 { 677 Rectangle aNewVisCells(GetVisCells(GetVisArea(mpViewShell, meSplitPos))); 678 679 Rectangle aNewPos(aNewVisCells); 680 681 if (aNewVisCells.IsOver(maVisCells)) 682 aNewPos.Union(maVisCells); 683 else 684 CommitTableModelChange(maVisCells.Top(), maVisCells.Left(), maVisCells.Bottom(), maVisCells.Right(), AccessibleTableModelChangeType::UPDATE); 685 686 maVisCells = aNewVisCells; 687 688 CommitTableModelChange(aNewPos.Top(), aNewPos.Left(), aNewPos.Bottom(), aNewPos.Right(), AccessibleTableModelChangeType::UPDATE); 689 } 690 }*/ 691 // no longer needed, because the document calls the BoundingBoxChanged method 692 /* else if (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED) 693 { 694 AccessibleEventObject aEvent; 695 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED; 696 aEvent.Source = uno::Reference< XAccessibleContext >(this); 697 698 CommitChange(aEvent); 699 }*/ 700 } 701 else if (rHint.ISA( ScUpdateRefHint )) 702 { 703 const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint; 704 if (rRef.GetMode() == URM_INSDEL && rRef.GetDz() == 0) //#107250# test whether table is inserted or deleted 705 { 706 if (((rRef.GetRange().aStart.Col() == maRange.aStart.Col()) && 707 (rRef.GetRange().aEnd.Col() == maRange.aEnd.Col())) || 708 ((rRef.GetRange().aStart.Row() == maRange.aStart.Row()) && 709 (rRef.GetRange().aEnd.Row() == maRange.aEnd.Row()))) 710 { 711 // ignore next SC_HINT_DATACHANGED notification 712 mbDelIns = sal_True; 713 714 sal_Int16 nId(0); 715 SCsCOL nX(rRef.GetDx()); 716 SCsROW nY(rRef.GetDy()); 717 ScRange aRange(rRef.GetRange()); 718 if ((nX < 0) || (nY < 0)) 719 { 720 DBG_ASSERT(!((nX < 0) && (nY < 0)), "should not be possible to remove row and column at the same time"); 721 nId = AccessibleTableModelChangeType::DELETE; 722 if (nX < 0) 723 { 724 nX = -nX; 725 nY = aRange.aEnd.Row() - aRange.aStart.Row(); 726 } 727 else 728 { 729 nY = -nY; 730 nX = aRange.aEnd.Col() - aRange.aStart.Col(); 731 } 732 } 733 else if ((nX > 0) || (nY > 0)) 734 { 735 DBG_ASSERT(!((nX > 0) && (nY > 0)), "should not be possible to add row and column at the same time"); 736 nId = AccessibleTableModelChangeType::INSERT; 737 if (nX < 0) 738 nY = aRange.aEnd.Row() - aRange.aStart.Row(); 739 else 740 nX = aRange.aEnd.Col() - aRange.aStart.Col(); 741 } 742 else 743 { 744 DBG_ERROR("is it a deletion or a insertion?"); 745 } 746 747 CommitTableModelChange(rRef.GetRange().aStart.Row(), 748 rRef.GetRange().aStart.Col(), 749 rRef.GetRange().aStart.Row() + nY, 750 rRef.GetRange().aStart.Col() + nX, nId); 751 752 AccessibleEventObject aEvent; 753 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 754 aEvent.Source = uno::Reference< XAccessibleContext >(this); 755 uno::Reference< XAccessible > xNew = mpAccCell; 756 aEvent.NewValue <<= xNew; 757 758 CommitChange(aEvent); 759 } 760 } 761 } 762 763 ScAccessibleTableBase::Notify(rBC, rHint); 764 } 765 void ScAccessibleSpreadsheet::RemoveSelection(ScMarkData &refScMarkData) 766 { 767 AccessibleEventObject aEvent; 768 aEvent.Source = uno::Reference< XAccessible >(this); 769 aEvent.OldValue <<= ::com::sun::star::uno::Any(); 770 MAP_ADDR_XACC::iterator miRemove = m_mapSelectionSend.begin(); 771 for(; miRemove != m_mapSelectionSend.end() ;) 772 { 773 if (refScMarkData.IsCellMarked(miRemove->first.Col(),miRemove->first.Row(),sal_True) || 774 refScMarkData.IsCellMarked(miRemove->first.Col(),miRemove->first.Row(),sal_False) ) 775 { 776 ++miRemove; 777 continue; 778 } 779 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; 780 aEvent.NewValue <<= miRemove->second; 781 CommitChange(aEvent); 782 MAP_ADDR_XACC::iterator miNext = miRemove; 783 ++miNext; 784 m_mapSelectionSend.erase(miRemove); 785 miRemove = miNext; 786 } 787 } 788 void ScAccessibleSpreadsheet::CommitFocusCell(const ScAddress &aNewCell) 789 { 790 OSL_ASSERT(!IsFormulaMode()); 791 if(IsFormulaMode()) 792 { 793 return ; 794 } 795 AccessibleEventObject aEvent; 796 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 797 aEvent.Source = uno::Reference< XAccessible >(this); 798 uno::Reference< XAccessible > xOld = mpAccCell; 799 mpAccCell->release(); 800 mpAccCell=NULL; 801 aEvent.OldValue <<= xOld; 802 mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col()); 803 mpAccCell->acquire(); 804 mpAccCell->Init(); 805 uno::Reference< XAccessible > xNew = mpAccCell; 806 aEvent.NewValue <<= xNew; 807 maActiveCell = aNewCell; 808 ScDocument* pScDoc= GetDocument(mpViewShell); 809 if (pScDoc) 810 { 811 pScDoc->GetString(maActiveCell.Col(),maActiveCell.Row(),maActiveCell.Tab(), m_strCurCellValue); 812 } 813 CommitChange(aEvent); 814 } 815 sal_Bool ScAccessibleSpreadsheet::IsSameMarkCell() 816 { 817 return m_LastMarkedRanges == *mpMarkedRanges; 818 } 819 //===== XAccessibleTable ================================================ 820 821 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders( ) 822 throw (uno::RuntimeException) 823 { 824 ScUnoGuard aGuard; 825 IsObjectValid(); 826 uno::Reference< XAccessibleTable > xAccessibleTable; 827 if( mpDoc && mbIsSpreadsheet ) 828 { 829 if( const ScRange* pRowRange = mpDoc->GetRepeatRowRange( mnTab ) ) 830 { 831 SCROW nStart = pRowRange->aStart.Row(); 832 SCROW nEnd = pRowRange->aEnd.Row(); 833 if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXROW) ) 834 xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( 0, nStart, mnTab, MAXCOL, nEnd, mnTab ) ) ); 835 } 836 } 837 return xAccessibleTable; 838 } 839 840 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleColumnHeaders( ) 841 throw (uno::RuntimeException) 842 { 843 ScUnoGuard aGuard; 844 IsObjectValid(); 845 uno::Reference< XAccessibleTable > xAccessibleTable; 846 if( mpDoc && mbIsSpreadsheet ) 847 { 848 if( const ScRange* pColRange = mpDoc->GetRepeatColRange( mnTab ) ) 849 { 850 SCCOL nStart = pColRange->aStart.Col(); 851 SCCOL nEnd = pColRange->aEnd.Col(); 852 if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXCOL) ) 853 xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( nStart, 0, mnTab, nEnd, MAXROW, mnTab ) ) ); 854 } 855 } 856 return xAccessibleTable; 857 } 858 859 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleRows( ) 860 throw (uno::RuntimeException) 861 { 862 ScUnoGuard aGuard; 863 IsObjectValid(); 864 uno::Sequence<sal_Int32> aSequence; 865 if (IsFormulaMode()) 866 { 867 return aSequence; 868 } 869 if (mpViewShell && mpViewShell->GetViewData()) 870 { 871 aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1); 872 const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData(); 873 sal_Int32* pSequence = aSequence.getArray(); 874 sal_Int32 nCount(0); 875 for (SCROW i = maRange.aStart.Row(); i <= maRange.aEnd.Row(); ++i) 876 { 877 if (rMarkdata.IsRowMarked(i)) 878 { 879 pSequence[nCount] = i; 880 ++nCount; 881 } 882 } 883 aSequence.realloc(nCount); 884 } 885 else 886 aSequence.realloc(0); 887 return aSequence; 888 } 889 890 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleColumns( ) 891 throw (uno::RuntimeException) 892 { 893 ScUnoGuard aGuard; 894 IsObjectValid(); 895 uno::Sequence<sal_Int32> aSequence; 896 if (IsFormulaMode()) 897 { 898 return aSequence; 899 } 900 if (mpViewShell && mpViewShell->GetViewData()) 901 { 902 aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1); 903 const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData(); 904 sal_Int32* pSequence = aSequence.getArray(); 905 sal_Int32 nCount(0); 906 for (SCCOL i = maRange.aStart.Col(); i <= maRange.aEnd.Col(); ++i) 907 { 908 if (rMarkdata.IsColumnMarked(i)) 909 { 910 pSequence[nCount] = i; 911 ++nCount; 912 } 913 } 914 aSequence.realloc(nCount); 915 } 916 else 917 aSequence.realloc(0); 918 return aSequence; 919 } 920 921 sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nRow ) 922 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 923 { 924 ScUnoGuard aGuard; 925 IsObjectValid(); 926 if (IsFormulaMode()) 927 { 928 return sal_False; 929 } 930 931 if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) 932 throw lang::IndexOutOfBoundsException(); 933 934 sal_Bool bResult(sal_False); 935 if (mpViewShell && mpViewShell->GetViewData()) 936 { 937 const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData(); 938 bResult = rMarkdata.IsRowMarked((SCROW)nRow); 939 } 940 return bResult; 941 } 942 943 sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 nColumn ) 944 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 945 { 946 ScUnoGuard aGuard; 947 IsObjectValid(); 948 949 if (IsFormulaMode()) 950 { 951 return sal_False; 952 } 953 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0)) 954 throw lang::IndexOutOfBoundsException(); 955 956 sal_Bool bResult(sal_False); 957 if (mpViewShell && mpViewShell->GetViewData()) 958 { 959 const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData(); 960 bResult = rMarkdata.IsColumnMarked((SCCOL)nColumn); 961 } 962 return bResult; 963 } 964 965 ScAccessibleCell* ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn) 966 { 967 ScAccessibleCell* pAccessibleCell = NULL; 968 if (IsFormulaMode()) 969 { 970 ScAddress aCellAddress(static_cast<SCCOL>(nColumn), nRow, mpViewShell->GetViewData()->GetTabNo()); 971 if ((aCellAddress == m_aFormulaActiveCell) && m_pAccFormulaCell) 972 { 973 pAccessibleCell = m_pAccFormulaCell; 974 } 975 else 976 pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, GetAccessibleIndexFormula(nRow, nColumn), meSplitPos, mpAccDoc); 977 } 978 else 979 { 980 ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn), 981 static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab()); 982 if ((aCellAddress == maActiveCell) && mpAccCell) 983 { 984 pAccessibleCell = mpAccCell; 985 } 986 else 987 pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc); 988 } 989 990 return pAccessibleCell; 991 } 992 993 uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) 994 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 995 { 996 ScUnoGuard aGuard; 997 IsObjectValid(); 998 if (!IsFormulaMode()) 999 { 1000 if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) || 1001 nRow < 0 || 1002 nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) || 1003 nColumn < 0) 1004 throw lang::IndexOutOfBoundsException(); 1005 } 1006 uno::Reference<XAccessible> xAccessible; 1007 ScAccessibleCell* pAccessibleCell = GetAccessibleCellAt(nRow, nColumn); 1008 xAccessible = pAccessibleCell; 1009 pAccessibleCell->Init(); 1010 return xAccessible; 1011 } 1012 1013 sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) 1014 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 1015 { 1016 ScUnoGuard aGuard; 1017 IsObjectValid(); 1018 1019 if (IsFormulaMode()) 1020 { 1021 ScAddress addr(static_cast<SCCOL>(nColumn), nRow, 0); 1022 return IsScAddrFormulaSel(addr); 1023 } 1024 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || 1025 (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) 1026 throw lang::IndexOutOfBoundsException(); 1027 1028 sal_Bool bResult(sal_False); 1029 if (mpViewShell) 1030 { 1031 const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData(); 1032 bResult = rMarkdata.IsCellMarked(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow)); 1033 } 1034 return bResult; 1035 } 1036 1037 //===== XAccessibleComponent ============================================ 1038 1039 uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtPoint( 1040 const awt::Point& rPoint ) 1041 throw (uno::RuntimeException) 1042 { 1043 uno::Reference< XAccessible > xAccessible; 1044 if (containsPoint(rPoint)) 1045 { 1046 ScUnoGuard aGuard; 1047 IsObjectValid(); 1048 if (mpViewShell) 1049 { 1050 SCsCOL nX; 1051 SCsROW nY; 1052 mpViewShell->GetViewData()->GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY); 1053 try{ 1054 xAccessible = getAccessibleCellAt(nY, nX); 1055 } 1056 catch( ::com::sun::star::lang::IndexOutOfBoundsException e) 1057 { 1058 return NULL; 1059 } 1060 } 1061 } 1062 return xAccessible; 1063 } 1064 1065 void SAL_CALL ScAccessibleSpreadsheet::grabFocus( ) 1066 throw (uno::RuntimeException) 1067 { 1068 if (getAccessibleParent().is()) 1069 { 1070 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); 1071 if (xAccessibleComponent.is()) 1072 xAccessibleComponent->grabFocus(); 1073 } 1074 } 1075 1076 sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getForeground( ) 1077 throw (uno::RuntimeException) 1078 { 1079 return COL_BLACK; 1080 } 1081 1082 sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getBackground( ) 1083 throw (uno::RuntimeException) 1084 { 1085 ScUnoGuard aGuard; 1086 IsObjectValid(); 1087 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; 1088 } 1089 1090 //===== XAccessibleContext ============================================== 1091 1092 uno::Reference<XAccessibleRelationSet> SAL_CALL ScAccessibleSpreadsheet::getAccessibleRelationSet(void) 1093 throw (::com::sun::star::uno::RuntimeException) 1094 { 1095 utl::AccessibleRelationSetHelper* pRelationSet = NULL; 1096 if(mpAccDoc) 1097 pRelationSet = mpAccDoc->GetRelationSet(NULL); 1098 if (!pRelationSet) 1099 pRelationSet = new utl::AccessibleRelationSetHelper(); 1100 return pRelationSet; 1101 } 1102 1103 uno::Reference<XAccessibleStateSet> SAL_CALL 1104 ScAccessibleSpreadsheet::getAccessibleStateSet(void) 1105 throw (uno::RuntimeException) 1106 { 1107 ScUnoGuard aGuard; 1108 uno::Reference<XAccessibleStateSet> xParentStates; 1109 if (getAccessibleParent().is()) 1110 { 1111 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1112 xParentStates = xParentContext->getAccessibleStateSet(); 1113 } 1114 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 1115 if (IsDefunc(xParentStates)) 1116 pStateSet->AddState(AccessibleStateType::DEFUNC); 1117 else 1118 { 1119 pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS); 1120 if (IsEditable(xParentStates)) 1121 pStateSet->AddState(AccessibleStateType::EDITABLE); 1122 pStateSet->AddState(AccessibleStateType::ENABLED); 1123 pStateSet->AddState(AccessibleStateType::FOCUSABLE); 1124 if (IsFocused()) 1125 pStateSet->AddState(AccessibleStateType::FOCUSED); 1126 pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE); 1127 pStateSet->AddState(AccessibleStateType::OPAQUE); 1128 pStateSet->AddState(AccessibleStateType::SELECTABLE); 1129 if (IsCompleteSheetSelected()) 1130 pStateSet->AddState(AccessibleStateType::SELECTED); 1131 if (isShowing()) 1132 pStateSet->AddState(AccessibleStateType::SHOWING); 1133 if (isVisible()) 1134 pStateSet->AddState(AccessibleStateType::VISIBLE); 1135 } 1136 return pStateSet; 1137 } 1138 1139 ///===== XAccessibleSelection =========================================== 1140 1141 void SAL_CALL 1142 ScAccessibleSpreadsheet::selectAccessibleChild( sal_Int32 nChildIndex ) 1143 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1144 { 1145 ScUnoGuard aGuard; 1146 IsObjectValid(); 1147 if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) 1148 throw lang::IndexOutOfBoundsException(); 1149 1150 if (mpViewShell) 1151 { 1152 sal_Int32 nCol(getAccessibleColumn(nChildIndex)); 1153 sal_Int32 nRow(getAccessibleRow(nChildIndex)); 1154 1155 SelectCell(nRow, nCol, sal_False); 1156 } 1157 } 1158 1159 void SAL_CALL 1160 ScAccessibleSpreadsheet::clearAccessibleSelection( ) 1161 throw (uno::RuntimeException) 1162 { 1163 ScUnoGuard aGuard; 1164 IsObjectValid(); 1165 if (mpViewShell) 1166 { 1167 if (!IsFormulaMode()) 1168 mpViewShell->Unmark(); 1169 } 1170 } 1171 1172 void SAL_CALL 1173 ScAccessibleSpreadsheet::selectAllAccessibleChildren( ) 1174 throw (uno::RuntimeException) 1175 { 1176 ScUnoGuard aGuard; 1177 IsObjectValid(); 1178 if (mpViewShell) 1179 { 1180 if (IsFormulaMode()) 1181 { 1182 ScViewData *pViewData = mpViewShell->GetViewData(); 1183 mpViewShell->InitRefMode( 0, 0, pViewData->GetTabNo(), SC_REFTYPE_REF ); 1184 pViewData->SetRefStart(0,0,pViewData->GetTabNo()); 1185 pViewData->SetRefStart(MAXCOL,MAXROW,pViewData->GetTabNo()); 1186 mpViewShell->UpdateRef(MAXCOL, MAXROW, pViewData->GetTabNo()); 1187 } 1188 else 1189 mpViewShell->SelectAll(); 1190 } 1191 } 1192 1193 sal_Int32 SAL_CALL 1194 ScAccessibleSpreadsheet::getSelectedAccessibleChildCount( ) 1195 throw (uno::RuntimeException) 1196 { 1197 ScUnoGuard aGuard; 1198 IsObjectValid(); 1199 sal_Int32 nResult(0); 1200 if (mpViewShell) 1201 { 1202 if (IsFormulaMode()) 1203 { 1204 nResult = GetRowAll() * GetColAll() ; 1205 } 1206 else 1207 { 1208 if (!mpMarkedRanges) 1209 { 1210 mpMarkedRanges = new ScRangeList(); 1211 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); 1212 //aMarkData.MarkToMulti(); 1213 aMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_False); 1214 } 1215 // is possible, because there shouldn't be overlapped ranges in it 1216 if (mpMarkedRanges) 1217 nResult = mpMarkedRanges->GetCellCount(); 1218 } 1219 } 1220 return nResult; 1221 } 1222 1223 uno::Reference<XAccessible > SAL_CALL 1224 ScAccessibleSpreadsheet::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 1225 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1226 { 1227 ScUnoGuard aGuard; 1228 IsObjectValid(); 1229 uno::Reference < XAccessible > xAccessible; 1230 if (IsFormulaMode()) 1231 { 1232 if(CheckChildIndex(nSelectedChildIndex)) 1233 { 1234 ScAddress addr = GetChildIndexAddress(nSelectedChildIndex); 1235 xAccessible = getAccessibleCellAt(addr.Row(), addr.Col()); 1236 } 1237 return xAccessible; 1238 } 1239 if (mpViewShell) 1240 { 1241 if (!mpMarkedRanges) 1242 { 1243 mpMarkedRanges = new ScRangeList(); 1244 mpViewShell->GetViewData()->GetMarkData().FillRangeListWithMarks(mpMarkedRanges, sal_False); 1245 } 1246 if (mpMarkedRanges) 1247 { 1248 //if (!mpSortedMarkedCells) 1249 // CreateSortedMarkedCells(); 1250 //if (mpSortedMarkedCells) 1251 //{ 1252 // if ((nSelectedChildIndex < 0) || 1253 // (mpSortedMarkedCells->size() <= static_cast<sal_uInt32>(nSelectedChildIndex))) 1254 // throw lang::IndexOutOfBoundsException(); 1255 // else 1256 // xAccessible = getAccessibleCellAt((*mpSortedMarkedCells)[nSelectedChildIndex].Row(), (*mpSortedMarkedCells)[nSelectedChildIndex].Col()); 1257 if ((nSelectedChildIndex < 0) || 1258 (mpMarkedRanges->GetCellCount() <= static_cast<sal_uInt32>(nSelectedChildIndex))) 1259 { 1260 throw lang::IndexOutOfBoundsException(); 1261 } 1262 ScMyAddress addr = CalcScAddressFromRangeList(mpMarkedRanges,nSelectedChildIndex); 1263 if( m_mapSelectionSend.find(addr) != m_mapSelectionSend.end() ) 1264 xAccessible = m_mapSelectionSend[addr]; 1265 else 1266 xAccessible = getAccessibleCellAt(addr.Row(), addr.Col()); 1267 } 1268 } 1269 return xAccessible; 1270 } 1271 1272 void SAL_CALL 1273 ScAccessibleSpreadsheet::deselectAccessibleChild( sal_Int32 nChildIndex ) 1274 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1275 { 1276 ScUnoGuard aGuard; 1277 IsObjectValid(); 1278 1279 if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) 1280 throw lang::IndexOutOfBoundsException(); 1281 1282 if (mpViewShell) 1283 { 1284 sal_Int32 nCol(getAccessibleColumn(nChildIndex)); 1285 sal_Int32 nRow(getAccessibleRow(nChildIndex)); 1286 1287 if (IsFormulaMode()) 1288 { 1289 if(IsScAddrFormulaSel( 1290 ScAddress(static_cast<SCCOL>(nCol), nRow,mpViewShell->GetViewData()->GetTabNo())) 1291 ) 1292 { 1293 SelectCell(nRow, nCol, sal_True); 1294 } 1295 return ; 1296 } 1297 if (mpViewShell->GetViewData()->GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow))) 1298 SelectCell(nRow, nCol, sal_True); 1299 } 1300 } 1301 1302 void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect) 1303 { 1304 if (IsFormulaMode()) 1305 { 1306 if (bDeselect) 1307 {//?? 1308 return ; 1309 } 1310 else 1311 { 1312 ScViewData *pViewData = mpViewShell->GetViewData(); 1313 1314 mpViewShell->InitRefMode( static_cast<SCCOL>(nCol), nRow, pViewData->GetTabNo(), SC_REFTYPE_REF ); 1315 mpViewShell->UpdateRef(static_cast<SCCOL>(nCol), nRow, pViewData->GetTabNo()); 1316 } 1317 return ; 1318 } 1319 mpViewShell->SetTabNo( maRange.aStart.Tab() ); 1320 1321 mpViewShell->DoneBlockMode( sal_True ); // continue selecting 1322 mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, sal_False, sal_False ); 1323 1324 mpViewShell->SelectionChanged(); 1325 } 1326 1327 //===== XServiceInfo ==================================================== 1328 1329 ::rtl::OUString SAL_CALL ScAccessibleSpreadsheet::getImplementationName(void) 1330 throw (uno::RuntimeException) 1331 { 1332 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleSpreadsheet")); 1333 } 1334 1335 uno::Sequence< ::rtl::OUString> SAL_CALL 1336 ScAccessibleSpreadsheet::getSupportedServiceNames (void) 1337 throw (uno::RuntimeException) 1338 { 1339 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleTableBase::getSupportedServiceNames(); 1340 sal_Int32 nOldSize(aSequence.getLength()); 1341 aSequence.realloc(nOldSize + 1); 1342 ::rtl::OUString* pNames = aSequence.getArray(); 1343 1344 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheet")); 1345 1346 return aSequence; 1347 } 1348 1349 //===== XTypeProvider ======================================================= 1350 1351 uno::Sequence<sal_Int8> SAL_CALL 1352 ScAccessibleSpreadsheet::getImplementationId(void) 1353 throw (uno::RuntimeException) 1354 { 1355 ScUnoGuard aGuard; 1356 IsObjectValid(); 1357 static uno::Sequence<sal_Int8> aId; 1358 if (aId.getLength() == 0) 1359 { 1360 aId.realloc (16); 1361 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 1362 } 1363 return aId; 1364 } 1365 1366 ///===== XAccessibleEventBroadcaster ===================================== 1367 1368 void SAL_CALL ScAccessibleSpreadsheet::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener) 1369 throw (uno::RuntimeException) 1370 { 1371 ScUnoGuard aGuard; 1372 IsObjectValid(); 1373 ScAccessibleTableBase::addEventListener(xListener); 1374 } 1375 1376 //==== internal ========================================================= 1377 1378 Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const 1379 throw (uno::RuntimeException) 1380 { 1381 Rectangle aRect; 1382 if (mpViewShell) 1383 { 1384 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 1385 if (pWindow) 1386 aRect = pWindow->GetWindowExtentsRelative(NULL); 1387 } 1388 return aRect; 1389 } 1390 1391 Rectangle ScAccessibleSpreadsheet::GetBoundingBox() const 1392 throw (uno::RuntimeException) 1393 { 1394 Rectangle aRect; 1395 if (mpViewShell) 1396 { 1397 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); 1398 if (pWindow) 1399 //#101986#; extends to the same window, because the parent is the document and it has the same window 1400 aRect = pWindow->GetWindowExtentsRelative(pWindow); 1401 } 1402 return aRect; 1403 } 1404 1405 sal_Bool ScAccessibleSpreadsheet::IsDefunc( 1406 const uno::Reference<XAccessibleStateSet>& rxParentStates) 1407 { 1408 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() || 1409 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 1410 } 1411 1412 sal_Bool ScAccessibleSpreadsheet::IsEditable( 1413 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) 1414 { 1415 if (IsFormulaMode()) 1416 { 1417 return sal_False; 1418 } 1419 sal_Bool bProtected(sal_False); 1420 if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab())) 1421 bProtected = sal_True; 1422 return !bProtected; 1423 } 1424 1425 sal_Bool ScAccessibleSpreadsheet::IsFocused() 1426 { 1427 sal_Bool bFocused(sal_False); 1428 if (mpViewShell) 1429 { 1430 if (mpViewShell->GetViewData()->GetActivePart() == meSplitPos) 1431 bFocused = mpViewShell->GetActiveWin()->HasFocus(); 1432 } 1433 return bFocused; 1434 } 1435 1436 sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected() 1437 { 1438 if (IsFormulaMode()) 1439 { 1440 return sal_False; 1441 } 1442 sal_Bool bResult(sal_False); 1443 if(mpViewShell) 1444 { 1445 //#103800#; use a copy of MarkData 1446 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); 1447 aMarkData.MarkToMulti(); 1448 if (aMarkData.IsAllMarked(maRange)) 1449 bResult = sal_True; 1450 } 1451 return bResult; 1452 } 1453 1454 ScDocument* ScAccessibleSpreadsheet::GetDocument(ScTabViewShell* pViewShell) 1455 { 1456 ScDocument* pDoc = NULL; 1457 if (pViewShell) 1458 pDoc = pViewShell->GetViewData()->GetDocument(); 1459 return pDoc; 1460 } 1461 1462 Rectangle ScAccessibleSpreadsheet::GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos) 1463 { 1464 Rectangle aVisArea; 1465 if (pViewShell) 1466 { 1467 Window* pWindow = pViewShell->GetWindowByPos(eSplitPos); 1468 if (pWindow) 1469 { 1470 aVisArea.SetPos(pViewShell->GetViewData()->GetPixPos(eSplitPos)); 1471 aVisArea.SetSize(pWindow->GetSizePixel()); 1472 } 1473 } 1474 return aVisArea; 1475 } 1476 1477 Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea) 1478 { 1479 if (mpViewShell) 1480 { 1481 SCsCOL nStartX, nEndX; 1482 SCsROW nStartY, nEndY; 1483 1484 mpViewShell->GetViewData()->GetPosFromPixel( 1, 1, meSplitPos, nStartX, nStartY); 1485 mpViewShell->GetViewData()->GetPosFromPixel( rVisArea.GetWidth(), rVisArea.GetHeight(), meSplitPos, nEndX, nEndY); 1486 1487 return Rectangle(nStartX, nStartY, nEndX, nEndY); 1488 } 1489 else 1490 return Rectangle(); 1491 } 1492 sal_Bool SAL_CALL ScAccessibleSpreadsheet::selectRow( sal_Int32 row ) 1493 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1494 { 1495 if (IsFormulaMode()) 1496 { 1497 return sal_False; 1498 } 1499 1500 mpViewShell->SetTabNo( maRange.aStart.Tab() ); 1501 mpViewShell->DoneBlockMode( sal_True ); // continue selecting 1502 mpViewShell->InitBlockMode( 0, row, maRange.aStart.Tab(), sal_False, sal_False, sal_True ); 1503 mpViewShell->MarkCursor( MAXCOL, row, maRange.aStart.Tab(), sal_False, sal_True ); 1504 mpViewShell->SelectionChanged(); 1505 return sal_True; 1506 } 1507 1508 sal_Bool SAL_CALL ScAccessibleSpreadsheet::selectColumn( sal_Int32 column ) 1509 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1510 { 1511 if (IsFormulaMode()) 1512 { 1513 return sal_False; 1514 } 1515 1516 mpViewShell->SetTabNo( maRange.aStart.Tab() ); 1517 mpViewShell->DoneBlockMode( sal_True ); // continue selecting 1518 mpViewShell->InitBlockMode( static_cast<SCCOL>(column), 0, maRange.aStart.Tab(), sal_False, sal_True, sal_False ); 1519 mpViewShell->MarkCursor( static_cast<SCCOL>(column), MAXROW, maRange.aStart.Tab(), sal_True, sal_False ); 1520 mpViewShell->SelectionChanged(); 1521 return sal_True; 1522 } 1523 1524 sal_Bool SAL_CALL ScAccessibleSpreadsheet::unselectRow( sal_Int32 row ) 1525 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1526 { 1527 if (IsFormulaMode()) 1528 { 1529 return sal_False; 1530 } 1531 1532 mpViewShell->SetTabNo( maRange.aStart.Tab() ); 1533 mpViewShell->DoneBlockMode( sal_True ); // continue selecting 1534 mpViewShell->InitBlockMode( 0, row, maRange.aStart.Tab(), sal_False, sal_False, sal_True, sal_True ); 1535 mpViewShell->MarkCursor( MAXCOL, row, maRange.aStart.Tab(), sal_False, sal_True ); 1536 mpViewShell->SelectionChanged(); 1537 mpViewShell->DoneBlockMode( sal_True ); 1538 return sal_True; 1539 } 1540 1541 sal_Bool SAL_CALL ScAccessibleSpreadsheet::unselectColumn( sal_Int32 column ) 1542 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1543 { 1544 if (IsFormulaMode()) 1545 { 1546 return sal_False; 1547 } 1548 1549 mpViewShell->SetTabNo( maRange.aStart.Tab() ); 1550 mpViewShell->DoneBlockMode( sal_True ); // continue selecting 1551 mpViewShell->InitBlockMode( static_cast<SCCOL>(column), 0, maRange.aStart.Tab(), sal_False, sal_True, sal_False, sal_True ); 1552 mpViewShell->MarkCursor( static_cast<SCCOL>(column), MAXROW, maRange.aStart.Tab(), sal_True, sal_False ); 1553 mpViewShell->SelectionChanged(); 1554 mpViewShell->DoneBlockMode( sal_True ); 1555 return sal_True; 1556 } 1557 1558 void ScAccessibleSpreadsheet::FireFirstCellFocus() 1559 { 1560 if (IsFormulaMode()) 1561 { 1562 return ; 1563 } 1564 if (mbIsFocusSend) 1565 { 1566 return ; 1567 } 1568 mbIsFocusSend = sal_True; 1569 AccessibleEventObject aEvent; 1570 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 1571 aEvent.Source = uno::Reference< XAccessible >(this); 1572 aEvent.NewValue <<= getAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col()); 1573 CommitChange(aEvent); 1574 } 1575 void ScAccessibleSpreadsheet::NotifyRefMode() 1576 { 1577 ScViewData *pViewData = mpViewShell->GetViewData(); 1578 sal_uInt16 nRefStartX =pViewData->GetRefStartX(); 1579 sal_Int32 nRefStartY=pViewData->GetRefStartY(); 1580 sal_uInt16 nRefEndX=pViewData->GetRefEndX(); 1581 sal_Int32 nRefEndY=pViewData->GetRefEndY(); 1582 ScAddress aFormulaAddr; 1583 if(!GetFormulaCurrentFocusCell(aFormulaAddr)) 1584 { 1585 return ; 1586 } 1587 if (m_aFormulaActiveCell != aFormulaAddr) 1588 {//New Focus 1589 m_nMinX =std::min(nRefStartX,nRefEndX); 1590 m_nMaxX =std::max(nRefStartX,nRefEndX); 1591 m_nMinY = std::min(nRefStartY,nRefEndY); 1592 m_nMaxY = std::max(nRefStartY,nRefEndY); 1593 RemoveFormulaSelection(); 1594 AccessibleEventObject aEvent; 1595 aEvent.Source = uno::Reference< XAccessible >(this); 1596 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; 1597 aEvent.Source = uno::Reference< XAccessible >(this); 1598 uno::Reference< XAccessible > xOld = m_pAccFormulaCell; 1599 aEvent.OldValue <<= xOld; 1600 m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(), aFormulaAddr.Col()); 1601 m_pAccFormulaCell->acquire(); 1602 m_pAccFormulaCell->Init(); 1603 uno::Reference< XAccessible > xNew = m_pAccFormulaCell; 1604 aEvent.NewValue <<= xNew; 1605 CommitChange(aEvent); 1606 if (nRefStartX == nRefEndX && nRefStartY == nRefEndY) 1607 {//Selection Single 1608 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1609 aEvent.NewValue <<= xNew; 1610 CommitChange(aEvent); 1611 m_mapFormulaSelectionSend.insert(MAP_ADDR_XACC::value_type(aFormulaAddr,xNew)); 1612 m_vecFormulaLastMyAddr.clear(); 1613 m_vecFormulaLastMyAddr.push_back(aFormulaAddr); 1614 } 1615 else 1616 { 1617 VEC_MYADDR vecCurSel; 1618 int nCurSize = (m_nMaxX - m_nMinX +1)*(m_nMaxY - m_nMinY +1) ; 1619 vecCurSel.reserve(nCurSize); 1620 for (sal_uInt16 x = m_nMinX ; x <= m_nMaxX ; ++x) 1621 { 1622 for (sal_Int32 y = m_nMinY ; y <= m_nMaxY ; ++y) 1623 { 1624 ScMyAddress aAddr(x,y,0); 1625 vecCurSel.push_back(aAddr); 1626 } 1627 } 1628 std::sort(vecCurSel.begin(), vecCurSel.end()); 1629 VEC_MYADDR vecNew; 1630 std::set_difference(vecCurSel.begin(),vecCurSel.end(), 1631 m_vecFormulaLastMyAddr.begin(),m_vecFormulaLastMyAddr.end(), 1632 std::back_insert_iterator<VEC_MYADDR>(vecNew)); 1633 int nNewSize = vecNew.size(); 1634 if ( nNewSize > 10 ) 1635 { 1636 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 1637 aEvent.NewValue <<= ::com::sun::star::uno::Any(); 1638 CommitChange(aEvent); 1639 } 1640 else 1641 { 1642 VEC_MYADDR::iterator viAddr = vecNew.begin(); 1643 for(; viAddr != vecNew.end() ; ++viAddr ) 1644 { 1645 uno::Reference< XAccessible > xChild; 1646 if (*viAddr == aFormulaAddr) 1647 { 1648 xChild = m_pAccFormulaCell; 1649 } 1650 else 1651 { 1652 xChild = getAccessibleCellAt(viAddr->Row(),viAddr->Col()); 1653 aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS; 1654 aEvent.NewValue <<= xChild; 1655 CommitChange(aEvent); 1656 } 1657 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; 1658 aEvent.NewValue <<= xChild; 1659 CommitChange(aEvent); 1660 m_mapFormulaSelectionSend.insert(MAP_ADDR_XACC::value_type(*viAddr,xChild)); 1661 } 1662 } 1663 m_vecFormulaLastMyAddr.swap(vecCurSel); 1664 } 1665 } 1666 m_aFormulaActiveCell = aFormulaAddr; 1667 } 1668 void ScAccessibleSpreadsheet::RemoveFormulaSelection(sal_Bool bRemoveAll ) 1669 { 1670 AccessibleEventObject aEvent; 1671 aEvent.Source = uno::Reference< XAccessible >(this); 1672 aEvent.OldValue <<= ::com::sun::star::uno::Any(); 1673 MAP_ADDR_XACC::iterator miRemove = m_mapFormulaSelectionSend.begin(); 1674 for(; miRemove != m_mapFormulaSelectionSend.end() ;) 1675 { 1676 if( !bRemoveAll && IsScAddrFormulaSel(miRemove->first) ) 1677 { 1678 ++miRemove; 1679 continue; 1680 } 1681 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; 1682 aEvent.NewValue <<= miRemove->second; 1683 CommitChange(aEvent); 1684 MAP_ADDR_XACC::iterator miNext = miRemove; 1685 ++miNext; 1686 m_mapFormulaSelectionSend.erase(miRemove); 1687 miRemove = miNext; 1688 } 1689 } 1690 sal_Bool ScAccessibleSpreadsheet::IsScAddrFormulaSel(const ScAddress &addr) const 1691 { 1692 if( addr.Col() >= m_nMinX && addr.Col() <= m_nMaxX && 1693 addr.Row() >= m_nMinY && addr.Row() <= m_nMaxY && 1694 addr.Tab() == mpViewShell->GetViewData()->GetTabNo() ) 1695 { 1696 return sal_True; 1697 } 1698 return sal_False; 1699 } 1700 sal_Bool ScAccessibleSpreadsheet::CheckChildIndex(sal_Int32 nIndex) const 1701 { 1702 sal_Int32 nMaxIndex = (m_nMaxX - m_nMinX +1)*(m_nMaxY - m_nMinY +1) -1 ; 1703 return nIndex <= nMaxIndex && nIndex >= 0 ; 1704 } 1705 ScAddress ScAccessibleSpreadsheet::GetChildIndexAddress(sal_Int32 nIndex) const 1706 { 1707 sal_Int32 nRowAll = GetRowAll(); 1708 sal_uInt16 nColAll = GetColAll(); 1709 if (nIndex < 0 || nIndex >= nRowAll * nColAll ) 1710 { 1711 return ScAddress(); 1712 } 1713 return ScAddress( 1714 static_cast<SCCOL>((nIndex - nIndex % nRowAll) / nRowAll + + m_nMinX), 1715 nIndex % nRowAll + m_nMinY, 1716 mpViewShell->GetViewData()->GetTabNo() 1717 ); 1718 } 1719 sal_Int32 ScAccessibleSpreadsheet::GetAccessibleIndexFormula( sal_Int32 nRow, sal_Int32 nColumn ) 1720 { 1721 sal_uInt16 nColRelative = sal_uInt16(nColumn) - GetColAll(); 1722 sal_Int32 nRowRelative = nRow - GetRowAll(); 1723 if (nRow < 0 || nColumn < 0 || nRowRelative >= GetRowAll() || nColRelative >= GetColAll() ) 1724 { 1725 return -1; 1726 } 1727 return GetRowAll() * nRowRelative + nColRelative; 1728 } 1729 sal_Bool ScAccessibleSpreadsheet::IsFormulaMode() 1730 { 1731 ScViewData *pViewData = mpViewShell->GetViewData(); 1732 m_bFormulaMode = pViewData->IsRefMode() || SC_MOD()->IsFormulaMode(); 1733 return m_bFormulaMode ; 1734 } 1735 sal_Bool ScAccessibleSpreadsheet::GetFormulaCurrentFocusCell(ScAddress &addr) 1736 { 1737 ScViewData *pViewData = mpViewShell->GetViewData(); 1738 sal_uInt16 nRefX=0; 1739 sal_Int32 nRefY=0; 1740 if(m_bFormulaLastMode) 1741 { 1742 nRefX=pViewData->GetRefEndX(); 1743 nRefY=pViewData->GetRefEndY(); 1744 } 1745 else 1746 { 1747 nRefX=pViewData->GetRefStartX(); 1748 nRefY=pViewData->GetRefStartY(); 1749 } 1750 if( /* Always true: nRefX >= 0 && */ nRefX <= MAXCOL && nRefY >= 0 && nRefY <= MAXROW) 1751 { 1752 addr = ScAddress(nRefX,nRefY,pViewData->GetTabNo()); 1753 return sal_True; 1754 } 1755 return sal_False; 1756 } 1757 uno::Reference < XAccessible > ScAccessibleSpreadsheet::GetActiveCell() 1758 { 1759 if( m_mapSelectionSend.find( maActiveCell ) != m_mapSelectionSend.end() ) 1760 return m_mapSelectionSend[maActiveCell]; 1761 else 1762 return getAccessibleCellAt(maActiveCell.Row(), maActiveCell .Col()); 1763 } 1764