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