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