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