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