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