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