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