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