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