xref: /trunk/main/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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