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 "AccessibleDocument.hxx"
29 #include "AccessibleSpreadsheet.hxx"
30 #include "tabvwsh.hxx"
31 #include "AccessibilityHints.hxx"
32 #include "document.hxx"
33 #include "drwlayer.hxx"
34 #include "unoguard.hxx"
35 #include "shapeuno.hxx"
36 #include "DrawModelBroadcaster.hxx"
37 #include "drawview.hxx"
38 #include "gridwin.hxx"
39 #include "AccessibleEditObject.hxx"
40 #include "scresid.hxx"
41 #ifndef SC_SC_HRC
42 #include "sc.hrc"
43 #endif
44 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
45 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
46 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
47 #endif
48 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
49 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
50 #endif
51 #include <com/sun/star/view/XSelectionSupplier.hpp>
52 #include <com/sun/star/drawing/XShape.hpp>
53 #include <com/sun/star/drawing/XShapes.hpp>
54 
55 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
56 #include <unotools/accessiblestatesethelper.hxx>
57 #endif
58 #include <tools/debug.hxx>
59 #include <tools/gen.hxx>
60 #include <svx/svdpage.hxx>
61 #include <svx/svdobj.hxx>
62 #include <svx/ShapeTypeHandler.hxx>
63 #include <svx/AccessibleShape.hxx>
64 #include <svx/AccessibleShapeTreeInfo.hxx>
65 #include <svx/AccessibleShapeInfo.hxx>
66 #include <comphelper/sequence.hxx>
67 #include <sfx2/viewfrm.hxx>
68 #include <svx/unoshcol.hxx>
69 #include <svx/unoshape.hxx>
70 #include <unotools/accessiblerelationsethelper.hxx>
71 #include <toolkit/helper/convert.hxx>
72 
73 //IAccessibility2 Implementation 2009-----
74 #include <svx/AccessibleControlShape.hxx>
75 #include <svx/AccessibleShape.hxx>
76 #include <svx/ShapeTypeHandler.hxx>
77 #include <svx/SvxShapeTypes.hxx>
78 #include <sfx2/objsh.hxx>
79 #include <editeng/editview.hxx>
80 #include <editeng/editeng.hxx>
81 //-----IAccessibility2 Implementation 2009
82 #include <list>
83 #include <algorithm>
84 //IAccessibility2 Implementation 2009-----
85 #include "AccessibleCell.hxx"
86 
87 #include "svx/unoapi.hxx"
88 #include "scmod.hxx"
89 //-----IAccessibility2 Implementation 2009
90 using namespace	::com::sun::star;
91 using namespace	::com::sun::star::accessibility;
92 using ::std::for_each;
93 
94 	//=====  internal  ========================================================
95 
96 struct ScAccessibleShapeData
97 {
98 	ScAccessibleShapeData() : pAccShape(NULL), pRelationCell(NULL), bSelected(sal_False), bSelectable(sal_True) {}
99 	~ScAccessibleShapeData();
100 	mutable ::accessibility::AccessibleShape* pAccShape;
101     mutable ScAddress*          pRelationCell; // if it is NULL this shape is anchored on the table
102 //    SdrObject*                  pShape;
103 	com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
104 	mutable sal_Bool			bSelected;
105     sal_Bool                    bSelectable;
106 };
107 
108 ScAccessibleShapeData::~ScAccessibleShapeData()
109 {
110     if (pAccShape)
111     {
112         pAccShape->dispose();
113         pAccShape->release();
114     }
115 }
116 
117 struct ScShapeDataLess
118 {
119     rtl::OUString msLayerId;
120     rtl::OUString msZOrder;
121     ScShapeDataLess()
122         : msLayerId(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )),
123         msZOrder(RTL_CONSTASCII_USTRINGPARAM( "ZOrder" ))
124     {
125     }
126     void ConvertLayerId(sal_Int16& rLayerID) const // changes the number of the LayerId so it the accessibility order
127     {
128         switch (rLayerID)
129         {
130         case SC_LAYER_FRONT:
131             rLayerID = 1;
132             break;
133         case SC_LAYER_BACK:
134             rLayerID = 0;
135             break;
136         case SC_LAYER_INTERN:
137             rLayerID = 2;
138             break;
139         case SC_LAYER_CONTROLS:
140             rLayerID = 3;
141             break;
142         }
143     }
144     sal_Bool LessThanSheet(const ScAccessibleShapeData* pData) const
145     {
146         sal_Bool bResult(sal_False);
147         uno::Reference< beans::XPropertySet> xProps(pData->xShape, uno::UNO_QUERY);
148         if (xProps.is())
149         {
150 			uno::Any aPropAny = xProps->getPropertyValue(msLayerId);
151 			sal_Int16 nLayerID = 0;
152 			if( (aPropAny >>= nLayerID) )
153             {
154                 if (nLayerID == SC_LAYER_BACK)
155                     bResult = sal_True;
156             }
157         }
158         return bResult;
159     }
160     sal_Bool operator()(const ScAccessibleShapeData* pData1, const ScAccessibleShapeData* pData2) const
161     {
162         sal_Bool bResult(sal_False);
163         if (pData1 && pData2)
164         {
165             uno::Reference< beans::XPropertySet> xProps1(pData1->xShape, uno::UNO_QUERY);
166             uno::Reference< beans::XPropertySet> xProps2(pData2->xShape, uno::UNO_QUERY);
167             if (xProps1.is() && xProps2.is())
168             {
169 				uno::Any aPropAny1 = xProps1->getPropertyValue(msLayerId);
170                 uno::Any aPropAny2 = xProps2->getPropertyValue(msLayerId);
171 				sal_Int16 nLayerID1(0);
172                 sal_Int16 nLayerID2(0);
173 				if( (aPropAny1 >>= nLayerID1) && (aPropAny2 >>= nLayerID2) )
174                 {
175                     if (nLayerID1 == nLayerID2)
176                     {
177 		                uno::Any aAny1 = xProps1->getPropertyValue(msZOrder);
178 		                sal_Int32 nZOrder1 = 0;
179 		                uno::Any aAny2 = xProps2->getPropertyValue(msZOrder);
180 		                sal_Int32 nZOrder2 = 0;
181 		                if ( (aAny1 >>= nZOrder1) && (aAny2 >>= nZOrder2) )
182                             bResult = (nZOrder1 < nZOrder2);
183                     }
184                     else
185                     {
186                         ConvertLayerId(nLayerID1);
187                         ConvertLayerId(nLayerID2);
188                         bResult = (nLayerID1 < nLayerID2);
189                     }
190                 }
191             }
192         }
193         else if (pData1 && !pData2)
194             bResult = LessThanSheet(pData1);
195         else if (!pData1 && pData2)
196             bResult = !LessThanSheet(pData2);
197         else
198             bResult = sal_False;
199         return bResult;
200     }
201 };
202 
203 struct DeselectShape
204 {
205 	void operator() (const ScAccessibleShapeData* pAccShapeData) const
206 	{
207         if (pAccShapeData)
208         {
209 		    pAccShapeData->bSelected = sal_False;
210 		    if (pAccShapeData->pAccShape)
211 			    pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED);
212         }
213 	}
214 };
215 
216 struct SelectShape
217 {
218     uno::Reference < drawing::XShapes > xShapes;
219     SelectShape(uno::Reference<drawing::XShapes>& xTemp) : xShapes(xTemp) {}
220 	void operator() (const ScAccessibleShapeData* pAccShapeData) const
221     {
222         if (pAccShapeData && pAccShapeData->bSelectable)
223         {
224 	        pAccShapeData->bSelected = sal_True;
225 	        if (pAccShapeData->pAccShape)
226 		        pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED);
227             if (xShapes.is())
228                 xShapes->add(pAccShapeData->xShape);
229         }
230     }
231 };
232 
233 struct Destroy
234 {
235     void operator() (ScAccessibleShapeData* pData)
236     {
237         if (pData)
238             DELETEZ(pData);
239     }
240 };
241 
242 class ScChildrenShapes : public SfxListener,
243 	public ::accessibility::IAccessibleParent
244 {
245 public:
246     ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
247     ~ScChildrenShapes();
248 
249     ///=====  SfxListener  =====================================================
250 
251 	virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
252 
253     ///=====  IAccessibleParent  ===============================================
254 
255     virtual sal_Bool ReplaceChild (
256         ::accessibility::AccessibleShape* pCurrentChild,
257 		const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
258 		const long _nIndex,
259 		const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
260 	)	throw (::com::sun::star::uno::RuntimeException);
261 
262 //IAccessibility2 Implementation 2009-----
263 	virtual ::accessibility::AccessibleControlShape* GetAccControlShapeFromModel
264 		(::com::sun::star::beans::XPropertySet* pSet)
265 		throw (::com::sun::star::uno::RuntimeException);
266 	virtual  ::com::sun::star::uno::Reference<
267             ::com::sun::star::accessibility::XAccessible>
268         GetAccessibleCaption (const ::com::sun::star::uno::Reference<
269             ::com::sun::star::drawing::XShape>& xShape)
270 			throw (::com::sun::star::uno::RuntimeException);
271 //-----IAccessibility2 Implementation 2009
272     ///=====  Internal  ========================================================
273     void SetDrawBroadcaster();
274 
275     sal_Int32 GetCount() const;
276     uno::Reference< XAccessible > Get(const ScAccessibleShapeData* pData) const;
277     uno::Reference< XAccessible > Get(sal_Int32 nIndex) const;
278 	uno::Reference< XAccessible > GetAt(const awt::Point& rPoint) const;
279 
280 	// gets the index of the shape starting on 0 (without the index of the table)
281 	// returns the selected shape
282 	sal_Bool IsSelected(sal_Int32 nIndex,
283 		com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape) const;
284 
285     sal_Bool SelectionChanged();
286 
287     void Select(sal_Int32 nIndex);
288     void DeselectAll(); // deselect also the table
289     void SelectAll();
290     sal_Int32 GetSelectedCount() const;
291     uno::Reference< XAccessible > GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const;
292     void Deselect(sal_Int32 nChildIndex);
293 
294     SdrPage* GetDrawPage() const;
295 
296     utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;
297 
298     void VisAreaChanged() const;
299 private:
300     typedef std::vector<ScAccessibleShapeData*> SortedShapes;
301 
302     mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order
303 
304     mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo;
305 	mutable com::sun::star::uno::Reference<com::sun::star::view::XSelectionSupplier> xSelectionSupplier;
306 	mutable sal_uInt32 mnSdrObjCount;
307 	mutable sal_uInt32 mnShapesSelected;
308     ScTabViewShell* mpViewShell;
309     ScAccessibleDocument* mpAccessibleDocument;
310     ScSplitPos meSplitPos;
311 
312     void FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const;
313     sal_Bool FindSelectedShapesChanges(const com::sun::star::uno::Reference<com::sun::star::drawing::XShapes>& xShapes, sal_Bool bCommitChange) const;
314 	void FillSelectionSupplier() const;
315 
316     ScAddress* GetAnchor(const uno::Reference<drawing::XShape>& xShape) const;
317     uno::Reference<XAccessibleRelationSet> GetRelationSet(const ScAccessibleShapeData* pData) const;
318     void CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const;
319     void SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const;
320     void AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const;
321     void RemoveShape(const uno::Reference<drawing::XShape>& xShape) const;
322 
323     sal_Bool FindShape(const uno::Reference<drawing::XShape>& xShape, SortedShapes::iterator& rItr) const;
324 
325 	sal_Int8 Compare(const ScAccessibleShapeData* pData1,
326 		const ScAccessibleShapeData* pData2) const;
327 };
328 
329 ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
330     :
331     mnShapesSelected(0),
332     mpViewShell(pViewShell),
333     mpAccessibleDocument(pAccessibleDocument),
334     meSplitPos(eSplitPos)
335 {
336 	FillSelectionSupplier();
337     maZOrderedShapes.push_back(NULL); // add an element which represents the table
338 
339 	GetCount(); // fill list with filtered shapes (no internal shapes)
340 
341 	if (mnShapesSelected)
342 	{
343 		//set flag on every selected shape
344 		if (!xSelectionSupplier.is())
345 			throw uno::RuntimeException();
346 
347 		uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
348 		if (xShapes.is())
349 			FindSelectedShapesChanges(xShapes, sal_False);
350 	}
351     if (pViewShell)
352     {
353 	    SfxBroadcaster* pDrawBC = pViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
354 	    if (pDrawBC)
355         {
356 		    StartListening(*pDrawBC);
357 
358             maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
359             maShapeTreeInfo.SetSdrView(pViewShell->GetViewData()->GetScDrawView());
360             maShapeTreeInfo.SetController(NULL);
361             maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos));
362             maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
363         }
364     }
365 }
366 
367 ScChildrenShapes::~ScChildrenShapes()
368 {
369     std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy());
370     if (mpViewShell)
371     {
372 	    SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
373 	    if (pDrawBC)
374 		    EndListening(*pDrawBC);
375     }
376 }
377 
378 void ScChildrenShapes::SetDrawBroadcaster()
379 {
380     if (mpViewShell)
381     {
382 	    SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
383 	    if (pDrawBC)
384         {
385 		    StartListening(*pDrawBC, sal_True);
386 
387             maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(mpViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
388             maShapeTreeInfo.SetSdrView(mpViewShell->GetViewData()->GetScDrawView());
389             maShapeTreeInfo.SetController(NULL);
390             maShapeTreeInfo.SetWindow(mpViewShell->GetWindowByPos(meSplitPos));
391             maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
392         }
393     }
394 }
395 
396 void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint)
397 {
398 	if ( rHint.ISA( SdrHint ) )
399 	{
400 		const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
401         if (pSdrHint)
402         {
403             SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
404             if (pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->GetPage() == GetDrawPage()) &&
405                 (pObj->GetPage() == pObj->GetObjList()) ) //#108480# only do something if the object lies direct on the page
406             {
407                 switch (pSdrHint->GetKind())
408                 {
409                     case HINT_OBJCHG :         // Objekt geaendert
410                     {
411                         uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
412                         if (xShape.is())
413                         {
414                             ScShapeDataLess aLess;
415                             std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), aLess); // sort, because the z index or layer could be changed
416                             CheckWhetherAnchorChanged(xShape);
417                         }
418                     }
419                     break;
420                     case HINT_OBJINSERTED :    // Neues Zeichenobjekt eingefuegt
421                     {
422                         uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
423                         if (xShape.is())
424                             AddShape(xShape, sal_True);
425                     }
426                     break;
427                     case HINT_OBJREMOVED :     // Zeichenobjekt aus Liste entfernt
428                     {
429                         uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
430                         if (xShape.is())
431                             RemoveShape(xShape);
432                     }
433                     break;
434                     default :
435                     {
436                         // other events are not interesting
437                     }
438                     break;
439                 }
440             }
441         }
442     }
443 }
444 
445 sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurrentChild,
446 		const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
447 		const long _nIndex, const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo)
448     throw (uno::RuntimeException)
449 {
450 	// create the new child
451 	::accessibility::AccessibleShape* pReplacement = ::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
452 		::accessibility::AccessibleShapeInfo ( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex ),
453 		_rShapeTreeInfo
454 	);
455 	::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pReplacement );	// keep this alive (do this before calling Init!)
456 	if ( pReplacement )
457 		pReplacement->Init();
458 
459     sal_Bool bResult(sal_False);
460     if (pCurrentChild && pReplacement)
461     {
462         DBG_ASSERT(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted");
463         SortedShapes::iterator aItr;
464         FindShape(pCurrentChild->GetXShape(), aItr);
465         if (aItr != maZOrderedShapes.end() && (*aItr))
466         {
467             if ((*aItr)->pAccShape)
468             {
469                 DBG_ASSERT((*aItr)->pAccShape == pCurrentChild, "wrong child found");
470                 AccessibleEventObject aEvent;
471 			    aEvent.EventId = AccessibleEventId::CHILD;
472 			    aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
473                 aEvent.OldValue <<= uno::makeAny(uno::Reference<XAccessible>(pCurrentChild));
474 
475 			    mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
476 
477                 pCurrentChild->dispose();
478             }
479             (*aItr)->pAccShape = pReplacement;
480             AccessibleEventObject aEvent;
481 			aEvent.EventId = AccessibleEventId::CHILD;
482 			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
483             aEvent.NewValue <<= uno::makeAny(uno::Reference<XAccessible>(pReplacement));
484 
485 			mpAccessibleDocument->CommitChange(aEvent); // child is new - event
486             bResult = sal_True;
487         }
488     }
489     return bResult;
490 }
491 
492 //IAccessibility2 Implementation 2009-----
493 ::accessibility::AccessibleControlShape * ScChildrenShapes::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException)
494 {
495 	sal_Int32 count = GetCount();
496 	for (sal_Int32 index=0;index<count;index++)
497 	{
498 		ScAccessibleShapeData* pShape = maZOrderedShapes[index];
499             	if (pShape)
500    	     	{
501    	     		::accessibility::AccessibleShape* pAccShape = pShape->pAccShape;
502           	 	if (pAccShape  && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL)
503           	  	{
504 				::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape);
505 				if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet)
506 					return pCtlAccShape;
507 			  }
508             	}
509 	}
510 	return NULL;
511 }
512 ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible >
513 ScChildrenShapes::GetAccessibleCaption (const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape>& xShape)
514 			throw (::com::sun::star::uno::RuntimeException)
515 {
516 	sal_Int32 count = GetCount();
517 	for (sal_Int32 index=0;index<count;index++)
518 	{
519 		ScAccessibleShapeData* pShape = maZOrderedShapes[index];
520 			if (pShape && pShape->xShape == xShape )
521    	     	{
522 				::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild(  pShape->pAccShape );
523 //				uno::Reference<XAccessible> xNewChild( pShape->pAccShape , uno::UNO_QUERY );
524 				if(xNewChild.get())
525 				return xNewChild;
526 			}
527 	}
528 	return NULL;
529 }
530 //-----IAccessibility2 Implementation 2009
531 sal_Int32 ScChildrenShapes::GetCount() const
532 {
533 	SdrPage* pDrawPage = GetDrawPage();
534 	if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in
535 	{
536 		mnSdrObjCount = pDrawPage->GetObjCount();
537 		maZOrderedShapes.reserve(mnSdrObjCount + 1); // the table is always in
538 		for (sal_uInt32 i = 0; i < mnSdrObjCount; ++i)
539 		{
540 			SdrObject* pObj = pDrawPage->GetObj(i);
541 			if (pObj/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/)
542 			{
543 				uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY);
544                 AddShape(xShape, sal_False); //inserts in the correct order
545 			}
546 		}
547 	}
548 	return maZOrderedShapes.size();
549 }
550 
551 uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
552 {
553     if (!pData)
554         return NULL;
555 
556 	if (!pData->pAccShape)
557 	{
558 		::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
559         ::accessibility::AccessibleShapeInfo aShapeInfo(pData->xShape, mpAccessibleDocument, const_cast<ScChildrenShapes*>(this));
560 		pData->pAccShape = rShapeHandler.CreateAccessibleObject(
561 			aShapeInfo, maShapeTreeInfo);
562 		if (pData->pAccShape)
563         {
564 			pData->pAccShape->acquire();
565 			pData->pAccShape->Init();
566             if (pData->bSelected)
567                 pData->pAccShape->SetState(AccessibleStateType::SELECTED);
568             if (!pData->bSelectable)
569                 pData->pAccShape->ResetState(AccessibleStateType::SELECTABLE);
570             pData->pAccShape->SetRelationSet(GetRelationSet(pData));
571         }
572 	}
573     return pData->pAccShape;
574  }
575 
576 uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const
577 {
578 	if (maZOrderedShapes.size() <= 1)
579 		GetCount(); // fill list with filtered shapes (no internal shapes)
580 
581 	if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size())
582 		return NULL;
583 
584     return Get(maZOrderedShapes[nIndex]);
585 }
586 
587 uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint) const
588 {
589     uno::Reference<XAccessible> xAccessible;
590     if(mpViewShell)
591     {
592         sal_Int32 i(maZOrderedShapes.size() - 1);
593         sal_Bool bFound(sal_False);
594         while (!bFound && i >= 0)
595         {
596             ScAccessibleShapeData* pShape = maZOrderedShapes[i];
597             if (pShape)
598             {
599                 if (!pShape->pAccShape)
600                     Get(pShape);
601 
602                 if (pShape->pAccShape)
603                 {
604                     Point aPoint(VCLPoint(rPoint));
605                     aPoint -= VCLRectangle(pShape->pAccShape->getBounds()).TopLeft();
606                     if (pShape->pAccShape->containsPoint(AWTPoint(aPoint)))
607                     {
608                         xAccessible = pShape->pAccShape;
609                         bFound = sal_True;
610                     }
611                 }
612                 else
613                 {
614                     DBG_ERRORFILE("I should have an accessible shape now!");
615                 }
616             }
617             else
618                 bFound = sal_True; // this is the sheet and it lies before the rest of the shapes which are background shapes
619 
620             --i;
621         }
622     }
623     return xAccessible;
624 }
625 
626 sal_Bool ScChildrenShapes::IsSelected(sal_Int32 nIndex,
627 						uno::Reference<drawing::XShape>& rShape) const
628 {
629 	sal_Bool bResult (sal_False);
630 	if (maZOrderedShapes.size() <= 1)
631 		GetCount(); // fill list with filtered shapes (no internal shapes)
632 
633 	if (!xSelectionSupplier.is())
634 		throw uno::RuntimeException();
635 
636     if (!maZOrderedShapes[nIndex])
637         return sal_False;
638 
639     bResult = maZOrderedShapes[nIndex]->bSelected;
640     rShape = maZOrderedShapes[nIndex]->xShape;
641 
642 #ifdef DBG_UTIL // test whether it is truly selected by a slower method
643     uno::Reference< drawing::XShape > xReturnShape;
644     sal_Bool bDebugResult(sal_False);
645 	uno::Reference<container::XIndexAccess> xIndexAccess;
646 	xSelectionSupplier->getSelection() >>= xIndexAccess;
647 
648 	if (xIndexAccess.is())
649 	{
650 		sal_Int32 nCount(xIndexAccess->getCount());
651 		if (nCount)
652 		{
653 			uno::Reference< drawing::XShape > xShape;
654             uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape;
655 			sal_Int32 i(0);
656 			while (!bDebugResult && (i < nCount))
657 			{
658 				xIndexAccess->getByIndex(i) >>= xShape;
659 				if (xShape.is() && (xIndexShape.get() == xShape.get()))
660 				{
661 					bDebugResult = sal_True;
662 					xReturnShape = xShape;
663 				}
664 				else
665 					++i;
666 			}
667 		}
668 	}
669     DBG_ASSERT((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result");
670 #endif
671 
672     return bResult;
673 }
674 
675 sal_Bool ScChildrenShapes::SelectionChanged()
676 {
677     sal_Bool bResult(sal_False);
678 	if (!xSelectionSupplier.is())
679 		throw uno::RuntimeException();
680 
681 	uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
682 
683 	bResult = FindSelectedShapesChanges(xShapes, sal_True);
684 
685     return bResult;
686 }
687 
688 void ScChildrenShapes::Select(sal_Int32 nIndex)
689 {
690 	if (maZOrderedShapes.size() <= 1)
691 		GetCount(); // fill list with filtered shapes (no internal shapes)
692 
693 	if (!xSelectionSupplier.is())
694 		throw uno::RuntimeException();
695 
696     if (!maZOrderedShapes[nIndex])
697         return;
698 
699 	uno::Reference<drawing::XShape> xShape;
700 	if (!IsSelected(nIndex, xShape) && maZOrderedShapes[nIndex]->bSelectable)
701 	{
702 		uno::Reference<drawing::XShapes> xShapes;
703 		xSelectionSupplier->getSelection() >>= xShapes;
704 
705 		if (!xShapes.is())
706 			xShapes = new SvxShapeCollection();
707 
708 		xShapes->add(maZOrderedShapes[nIndex]->xShape);
709 
710         try
711         {
712             xSelectionSupplier->select(uno::makeAny(xShapes));
713 		    maZOrderedShapes[nIndex]->bSelected = sal_True;
714 		    if (maZOrderedShapes[nIndex]->pAccShape)
715 			    maZOrderedShapes[nIndex]->pAccShape->SetState(AccessibleStateType::SELECTED);
716         }
717         catch (lang::IllegalArgumentException&)
718         {
719         }
720 	}
721 }
722 
723 void ScChildrenShapes::DeselectAll()
724 {
725 	if (!xSelectionSupplier.is())
726 		throw uno::RuntimeException();
727 
728     sal_Bool bSomethingSelected(sal_True);
729     try
730     {
731         xSelectionSupplier->select(uno::Any()); //deselects all
732     }
733     catch (lang::IllegalArgumentException&)
734     {
735         DBG_ERRORFILE("nothing selected before");
736         bSomethingSelected = sal_False;
737     }
738 
739     if (bSomethingSelected)
740         std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), DeselectShape());
741 }
742 
743 void ScChildrenShapes::SelectAll()
744 {
745 	if (!xSelectionSupplier.is())
746 		throw uno::RuntimeException();
747 
748 	if (maZOrderedShapes.size() <= 1)
749 		GetCount(); // fill list with filtered shapes (no internal shapes)
750 
751     if (maZOrderedShapes.size() > 1)
752     {
753 	    uno::Reference<drawing::XShapes> xShapes;
754 	    xShapes = new SvxShapeCollection();
755 
756         try
757         {
758             std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), SelectShape(xShapes));
759     	    xSelectionSupplier->select(uno::makeAny(xShapes));
760         }
761         catch (lang::IllegalArgumentException&)
762         {
763             SelectionChanged(); // find all selected shapes and set the flags
764         }
765     }
766 }
767 
768 void ScChildrenShapes::FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const
769 {
770 	uno::Reference<container::XIndexAccess> xIndexAccess;
771 	xSelectionSupplier->getSelection() >>= xIndexAccess;
772 
773 	if (xIndexAccess.is())
774     {
775         sal_uInt32 nCount(xIndexAccess->getCount());
776         for (sal_uInt32 i = 0; i < nCount; ++i)
777         {
778     		uno::Reference<drawing::XShape> xShape;
779             xIndexAccess->getByIndex(i) >>= xShape;
780             if (xShape.is())
781                 rShapes.push_back(xShape);
782         }
783     }
784 }
785 
786 sal_Int32 ScChildrenShapes::GetSelectedCount() const
787 {
788 	if (!xSelectionSupplier.is())
789 		throw uno::RuntimeException();
790 
791     std::vector < uno::Reference < drawing::XShape > > aShapes;
792     FillShapes(aShapes);
793 
794     return aShapes.size();
795 }
796 
797 uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const
798 {
799     uno::Reference< XAccessible > xAccessible;
800 
801 	if (maZOrderedShapes.size() <= 1)
802 		GetCount(); // fill list with shapes
803 
804     if (!bTabSelected)
805     {
806         std::vector < uno::Reference < drawing::XShape > > aShapes;
807         FillShapes(aShapes);
808 
809 //IAccessibility2 Implementation 2009-----
810 		if(aShapes.size()<=0) return xAccessible;
811 //-----IAccessibility2 Implementation 2009
812         SortedShapes::iterator aItr;
813         if (FindShape(aShapes[nSelectedChildIndex], aItr))
814             xAccessible = Get(aItr - maZOrderedShapes.begin());
815     }
816     else
817     {
818         SortedShapes::iterator aItr = maZOrderedShapes.begin();
819         SortedShapes::iterator aEndItr = maZOrderedShapes.end();
820         sal_Bool bFound(sal_False);
821         while(!bFound && aItr != aEndItr)
822         {
823             if (*aItr)
824             {
825                 if ((*aItr)->bSelected)
826                 {
827                     if (nSelectedChildIndex == 0)
828                         bFound = sal_True;
829                     else
830                         --nSelectedChildIndex;
831                 }
832             }
833             else
834             {
835                 if (nSelectedChildIndex == 0)
836                     bFound = sal_True;
837                 else
838                     --nSelectedChildIndex;
839             }
840             if (!bFound)
841                 ++aItr;
842         }
843         if (bFound && *aItr)
844             xAccessible = (*aItr)->pAccShape;
845     }
846 
847     return xAccessible;
848 }
849 
850 void ScChildrenShapes::Deselect(sal_Int32 nChildIndex)
851 {
852 	uno::Reference<drawing::XShape> xShape;
853 	if (IsSelected(nChildIndex, xShape)) // returns false if it is the sheet
854 	{
855 		if (xShape.is())
856 		{
857 			uno::Reference<drawing::XShapes> xShapes;
858 			xSelectionSupplier->getSelection() >>= xShapes;
859 			if (xShapes.is())
860 				xShapes->remove(xShape);
861 
862             try
863             {
864 			    xSelectionSupplier->select(uno::makeAny(xShapes));
865             }
866             catch (lang::IllegalArgumentException&)
867             {
868                 DBG_ERRORFILE("something not selectable");
869             }
870 
871 			maZOrderedShapes[nChildIndex]->bSelected = sal_False;
872 			if (maZOrderedShapes[nChildIndex]->pAccShape)
873 				maZOrderedShapes[nChildIndex]->pAccShape->ResetState(AccessibleStateType::SELECTED);
874 		}
875 	}
876 }
877 
878 
879 SdrPage* ScChildrenShapes::GetDrawPage() const
880 {
881 	SCTAB nTab(mpAccessibleDocument->getVisibleTable());
882 	SdrPage* pDrawPage = NULL;
883 	if (mpViewShell)
884 	{
885 		ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
886 		if (pDoc && pDoc->GetDrawLayer())
887 		{
888 			ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
889 			if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
890 				pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
891 		}
892 	}
893 	return pDrawPage;
894 }
895 
896 struct SetRelation
897 {
898     const ScChildrenShapes* mpChildrenShapes;
899     mutable utl::AccessibleRelationSetHelper* mpRelationSet;
900     const ScAddress* mpAddress;
901     SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress)
902         :
903         mpChildrenShapes(pChildrenShapes),
904         mpRelationSet(NULL),
905         mpAddress(pAddress)
906     {
907     }
908 	void operator() (const ScAccessibleShapeData* pAccShapeData) const
909     {
910 	    if (pAccShapeData &&
911             ((!pAccShapeData->pRelationCell && !mpAddress) ||
912             (pAccShapeData->pRelationCell && mpAddress && (*(pAccShapeData->pRelationCell) == *mpAddress))))
913         {
914             if (!mpRelationSet)
915                 mpRelationSet = new utl::AccessibleRelationSetHelper();
916 
917             AccessibleRelation aRelation;
918             aRelation.TargetSet.realloc(1);
919             aRelation.TargetSet[0] = mpChildrenShapes->Get(pAccShapeData);
920             aRelation.RelationType = AccessibleRelationType::CONTROLLER_FOR;
921 
922             mpRelationSet->AddRelation(aRelation);
923         }
924     }
925 };
926 
927 utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const
928 {
929     SetRelation aSetRelation(this, pAddress);
930     ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation);
931     return aSetRelation.mpRelationSet;
932 }
933 
934 sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, sal_Bool /* bCommitChange */) const
935 {
936     sal_Bool bResult(sal_False);
937     SortedShapes aShapesList;
938     uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY);
939     if (xIndexAcc.is())
940     {
941         mnShapesSelected = xIndexAcc->getCount();
942         for (sal_uInt32 i = 0; i < mnShapesSelected; ++i)
943         {
944 			uno::Reference< drawing::XShape > xShape;
945             xIndexAcc->getByIndex(i) >>= xShape;
946             if (xShape.is())
947             {
948                 ScAccessibleShapeData* pShapeData = new ScAccessibleShapeData();
949                 pShapeData->xShape = xShape;
950                 aShapesList.push_back(pShapeData);
951             }
952         }
953     }
954     else
955         mnShapesSelected = 0;
956 //IAccessibility2 Implementation 2009-----
957 	SdrObject *pFocusedObj = NULL;
958 	if( mnShapesSelected == 1 && aShapesList.size() == 1)
959 	{
960 		pFocusedObj = GetSdrObjectFromXShape(aShapesList[0]->xShape);
961 	}
962 //-----IAccessibility2 Implementation 2009
963     ScShapeDataLess aLess;
964     std::sort(aShapesList.begin(), aShapesList.end(), aLess);
965 //IAccessibility2 Implementation 2009-----
966 	SortedShapes vecSelectedShapeAdd;
967 	SortedShapes vecSelectedShapeRemove;
968 	sal_Bool bHasSelect=sal_False;
969 //-----IAccessibility2 Implementation 2009
970     SortedShapes::iterator aXShapesItr(aShapesList.begin());
971     SortedShapes::const_iterator aXShapesEndItr(aShapesList.end());
972     SortedShapes::iterator aDataItr(maZOrderedShapes.begin());
973     SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end());
974     SortedShapes::const_iterator aFocusedItr = aDataEndItr;
975     while((aDataItr != aDataEndItr))
976     {
977         if (*aDataItr) // is it realy a shape or only the sheet
978         {
979             sal_Int8 nComp(0);
980             if (aXShapesItr == aXShapesEndItr)
981                 nComp = -1; // simulate that the Shape is lower, so the selction state will be removed
982             else
983                 nComp = Compare(*aDataItr, *aXShapesItr);
984             if (nComp == 0)
985             {
986                 if (!(*aDataItr)->bSelected)
987                 {
988                     (*aDataItr)->bSelected = sal_True;
989                     if ((*aDataItr)->pAccShape)
990                     {
991                         (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED);
992                         (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
993                         bResult = sal_True;
994 //IAccessibility2 Implementation 2009-----
995 						vecSelectedShapeAdd.push_back((*aDataItr));
996 //-----IAccessibility2 Implementation 2009
997                     }
998                     aFocusedItr = aDataItr;
999                 }
1000 //IAccessibility2 Implementation 2009-----
1001 				else
1002 				{
1003 					 bHasSelect = sal_True;
1004 				}
1005 //-----IAccessibility2 Implementation 2009
1006                 ++aDataItr;
1007                 ++aXShapesItr;
1008             }
1009             else if (nComp < 0)
1010             {
1011                 if ((*aDataItr)->bSelected)
1012                 {
1013                     (*aDataItr)->bSelected = sal_False;
1014                     if ((*aDataItr)->pAccShape)
1015                     {
1016                         (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED);
1017                         (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
1018                         bResult = sal_True;
1019 //IAccessibility2 Implementation 2009-----
1020 						vecSelectedShapeRemove.push_back(*aDataItr);
1021 //-----IAccessibility2 Implementation 2009
1022                     }
1023                 }
1024                 ++aDataItr;
1025             }
1026             else
1027             {
1028                 DBG_ERRORFILE("here is a selected shape which is not in the childlist");
1029                 ++aXShapesItr;
1030                 --mnShapesSelected;
1031             }
1032         }
1033         else
1034             ++aDataItr;
1035     }
1036 //IAccessibility2 Implementation 2009-----
1037 	bool bWinFocus=false;
1038 	ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1039 	if (pWin)
1040 	{
1041 		bWinFocus = pWin->HasFocus();
1042 	}
1043 	const SdrMarkList* pMarkList = NULL;
1044 	SdrObject* pMarkedObj = NULL;
1045 	SdrObject* pUpObj = NULL;
1046 	sal_Bool bIsFocuseMarked = sal_True;
1047 	if( mpViewShell && mnShapesSelected == 1 && bWinFocus)
1048 	{
1049 		ScDrawView* pScDrawView = mpViewShell->GetViewData()->GetScDrawView();
1050 		if( pScDrawView )
1051 		{
1052 			if( pScDrawView->GetMarkedObjectList().GetMarkCount() == 1 )
1053 			{
1054 				pMarkList = &(pScDrawView->GetMarkedObjectList());
1055 				pMarkedObj = pMarkList->GetMark(0)->GetMarkedSdrObj();
1056 				uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY);
1057 				if( aFocusedItr != aDataEndItr &&
1058 					(*aFocusedItr)->xShape.is() &&
1059 					xMarkedXShape.is() &&
1060 					(*aFocusedItr)->xShape != xMarkedXShape )
1061 					bIsFocuseMarked = sal_False;
1062 			}
1063 		}
1064 	}
1065     //if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1))
1066     if ( bIsFocuseMarked && (aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1) && bWinFocus)
1067 	{
1068         (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED);
1069 	}
1070 	else if( pFocusedObj && bWinFocus && pMarkList && pMarkList->GetMarkCount() == 1 && mnShapesSelected == 1 )
1071 	{
1072 		if( pMarkedObj )
1073 		{
1074 			uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY);
1075 			pUpObj = pMarkedObj->GetUpGroup();
1076 
1077 			if( pMarkedObj == pFocusedObj )
1078 			{
1079 				if( pUpObj )
1080 				{
1081 					uno::Reference< drawing::XShape > xUpGroupXShape (pUpObj->getUnoShape(), uno::UNO_QUERY);
1082 					uno::Reference < XAccessible > xAccGroupShape =
1083 						const_cast<ScChildrenShapes*>(this)->GetAccessibleCaption( xUpGroupXShape );
1084 					if( xAccGroupShape.is() )
1085 					{
1086 						::accessibility::AccessibleShape* pAccGroupShape =
1087 							static_cast< ::accessibility::AccessibleShape* >(xAccGroupShape.get());
1088 						if( pAccGroupShape )
1089 						{
1090 							sal_Int32 nCount =  pAccGroupShape->getAccessibleChildCount();
1091 							for( sal_Int32 i = 0; i < nCount; i++ )
1092 							{
1093 								uno::Reference<XAccessible> xAccShape = pAccGroupShape->getAccessibleChild(i);
1094 								if (xAccShape.is())
1095 								{
1096 									::accessibility::AccessibleShape* pChildAccShape =  static_cast< ::accessibility::AccessibleShape* >(xAccShape.get());
1097 									uno::Reference< drawing::XShape > xChildShape = pChildAccShape->GetXShape();
1098 									if (xChildShape == xMarkedXShape)
1099 									{
1100 			                			pChildAccShape->SetState(AccessibleStateType::FOCUSED);
1101 									}
1102 									else
1103 									{
1104 										pChildAccShape->ResetState(AccessibleStateType::FOCUSED);
1105 									}
1106 								}
1107 							}
1108 						}
1109 					}
1110 				}
1111 			}
1112 		}
1113 	}
1114 	if (vecSelectedShapeAdd.size() >= 10 )
1115 	{
1116 		AccessibleEventObject aEvent;
1117 		aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1118 		aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument);
1119 		mpAccessibleDocument->CommitChange(aEvent);
1120 	}
1121 	else
1122 	{
1123 		SortedShapes::iterator vi = vecSelectedShapeAdd.begin();
1124 		for (; vi != vecSelectedShapeAdd.end() ; ++vi )
1125 		{
1126 			AccessibleEventObject aEvent;
1127 			if (bHasSelect)
1128 			{
1129 				aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD;
1130 			}
1131 			else
1132 			{
1133 				aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1134 			}
1135 			aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument);
1136 			uno::Reference< XAccessible > xChild( (*vi)->pAccShape);
1137 			aEvent.NewValue <<= xChild;
1138 			mpAccessibleDocument->CommitChange(aEvent);
1139 		}
1140 	}
1141 	SortedShapes::iterator vi = vecSelectedShapeRemove.begin();
1142 	for (; vi != vecSelectedShapeRemove.end() ; ++vi )
1143 	{
1144 		AccessibleEventObject aEvent;
1145 		aEvent.EventId =  AccessibleEventId::SELECTION_CHANGED_REMOVE;
1146 		aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument);
1147 		uno::Reference< XAccessible > xChild( (*vi)->pAccShape);
1148 		aEvent.NewValue <<= xChild;
1149 		mpAccessibleDocument->CommitChange(aEvent);
1150 	}
1151 //-----IAccessibility2 Implementation 2009
1152     std::for_each(aShapesList.begin(), aShapesList.end(), Destroy());
1153 
1154     return bResult;
1155 }
1156 
1157 void ScChildrenShapes::FillSelectionSupplier() const
1158 {
1159 	if (!xSelectionSupplier.is() && mpViewShell)
1160 	{
1161 		SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame();
1162 		if (pViewFrame)
1163 		{
1164 			xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY);
1165 			if (xSelectionSupplier.is())
1166 			{
1167                 if (mpAccessibleDocument)
1168                     xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument);
1169 				uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY);
1170 				if (xShapes.is())
1171 					mnShapesSelected = xShapes->getCount();
1172 			}
1173 		}
1174 	}
1175 }
1176 
1177 ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const
1178 {
1179     ScAddress* pAddress = NULL;
1180     if (mpViewShell)
1181     {
1182 	    SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
1183         uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY);
1184 	    if (pShapeImp && xShapeProp.is())
1185 	    {
1186 		    SdrObject *pSdrObj = pShapeImp->GetSdrObject();
1187 		    if (pSdrObj)
1188 		    {
1189 			    if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
1190 			    {
1191                     ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
1192 				    if (pDoc)
1193 				    {
1194                         rtl::OUString sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape"));
1195 					    awt::Point aPoint(xShape->getPosition());
1196 					    awt::Size aSize(xShape->getSize());
1197 					    rtl::OUString sType(xShape->getShapeType());
1198 					    Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
1199 					    if ( sType.equals(sCaptionShape) )
1200 					    {
1201 						    awt::Point aRelativeCaptionPoint;
1202                             rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
1203 						    xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
1204 						    Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
1205 						    Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
1206 						    aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
1207 						    aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
1208 					    }
1209 					    ScRange aRange = pDoc->GetRange(mpAccessibleDocument->getVisibleTable(), aRectangle);
1210                         pAddress = new ScAddress(aRange.aStart);
1211 				    }
1212 			    }
1213 //			    else
1214 //				    do nothing, because it is always a NULL Pointer
1215 		    }
1216 	    }
1217     }
1218 
1219     return pAddress;
1220 }
1221 
1222 uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const
1223 {
1224     utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper();
1225 
1226     if(pData && pRelationSet && mpAccessibleDocument)
1227     {
1228         uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table
1229         if (pData->pRelationCell && xAccessible.is())
1230         {
1231             uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY);
1232             if (xAccTable.is())
1233                 xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col());
1234         }
1235         AccessibleRelation aRelation;
1236         aRelation.TargetSet.realloc(1);
1237         aRelation.TargetSet[0] = xAccessible;
1238         aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY;
1239         pRelationSet->AddRelation(aRelation);
1240     }
1241 
1242     return pRelationSet;
1243 }
1244 
1245 void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const
1246 {
1247     SortedShapes::iterator aItr;
1248     if (FindShape(xShape, aItr))
1249         SetAnchor(xShape, *aItr);
1250 }
1251 
1252 void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const
1253 {
1254     if (pData)
1255     {
1256         ScAddress* pAddress = GetAnchor(xShape);
1257         if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) ||
1258             (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell))
1259         {
1260             if (pData->pRelationCell)
1261                 delete pData->pRelationCell;
1262             pData->pRelationCell = pAddress;
1263             if (pData->pAccShape)
1264                 pData->pAccShape->SetRelationSet(GetRelationSet(pData));
1265         }
1266     }
1267 }
1268 
1269 void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const
1270 {
1271     SortedShapes::iterator aFindItr;
1272     if (!FindShape(xShape, aFindItr))
1273     {
1274         ScAccessibleShapeData* pShape = new ScAccessibleShapeData();
1275         pShape->xShape = xShape;
1276         SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape);
1277         SetAnchor(xShape, pShape);
1278 
1279         uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY);
1280         if (xShapeProp.is())
1281         {
1282             uno::Any aPropAny = xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(  "LayerID" )));
1283 		    sal_Int16 nLayerID = 0;
1284 		    if( aPropAny >>= nLayerID )
1285 		    {
1286                 if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
1287                     pShape->bSelectable = sal_False;
1288                 else
1289                     pShape->bSelectable = sal_True;
1290             }
1291         }
1292 
1293 
1294         if (!xSelectionSupplier.is())
1295 		    throw uno::RuntimeException();
1296 
1297         uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
1298 	    if (xEnumAcc.is())
1299 	    {
1300             uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration();
1301             if (xEnum.is())
1302             {
1303                 uno::Reference<drawing::XShape> xSelectedShape;
1304                 sal_Bool bFound(sal_False);
1305                 while (!bFound && xEnum->hasMoreElements())
1306                 {
1307                     xEnum->nextElement() >>= xSelectedShape;
1308                     if (xShape.is() && (xShape.get() == xSelectedShape.get()))
1309                     {
1310                         pShape->bSelected = sal_True;
1311                         bFound = sal_True;
1312                     }
1313                 }
1314             }
1315         }
1316         if (mpAccessibleDocument && bCommitChange)
1317         {
1318 			AccessibleEventObject aEvent;
1319 			aEvent.EventId = AccessibleEventId::CHILD;
1320 			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
1321 			aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin());
1322 
1323 			mpAccessibleDocument->CommitChange(aEvent); // new child - event
1324         }
1325     }
1326     else
1327     {
1328         DBG_ERRORFILE("shape is always in the list");
1329     }
1330 }
1331 
1332 void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const
1333 {
1334     SortedShapes::iterator aItr;
1335     if (FindShape(xShape, aItr))
1336     {
1337         if (mpAccessibleDocument)
1338         {
1339             uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin()));
1340 
1341             delete *aItr;
1342             maZOrderedShapes.erase(aItr);
1343 
1344             AccessibleEventObject aEvent;
1345 			aEvent.EventId = AccessibleEventId::CHILD;
1346 			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
1347             aEvent.OldValue <<= uno::makeAny(xOldAccessible);
1348 
1349 			mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
1350         }
1351         else
1352         {
1353             delete *aItr;
1354             maZOrderedShapes.erase(aItr);
1355         }
1356     }
1357     else
1358     {
1359         DBG_ERRORFILE("shape was not in internal list");
1360     }
1361 }
1362 
1363 sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const
1364 {
1365     sal_Bool bResult(sal_False);
1366     ScAccessibleShapeData aShape;
1367     aShape.xShape = xShape;
1368     ScShapeDataLess aLess;
1369     rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess);
1370     if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get()))
1371         bResult = sal_True; // if the shape is found
1372 
1373 #ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
1374     SortedShapes::iterator aDebugItr = maZOrderedShapes.begin();
1375     SortedShapes::iterator aEndItr = maZOrderedShapes.end();
1376     sal_Bool bFound(sal_False);
1377     while (!bFound && aDebugItr != aEndItr)
1378     {
1379         if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get()))
1380             bFound = sal_True;
1381         else
1382             ++aDebugItr;
1383     }
1384     sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end());
1385     DBG_ASSERT((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found");
1386 #endif
1387     return bResult;
1388 }
1389 
1390 sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1,
1391 		const ScAccessibleShapeData* pData2) const
1392 {
1393     ScShapeDataLess aLess;
1394 
1395     sal_Bool bResult1(aLess(pData1, pData2));
1396     sal_Bool bResult2(aLess(pData2, pData1));
1397 
1398 	sal_Int8 nResult(0);
1399     if (!bResult1 && bResult2)
1400         nResult = 1;
1401     else if (bResult1 && !bResult2)
1402         nResult = -1;
1403 
1404 	return nResult;
1405 }
1406 
1407 struct ScVisAreaChanged
1408 {
1409     ScAccessibleDocument* mpAccDoc;
1410     ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {}
1411 	void operator() (const ScAccessibleShapeData* pAccShapeData) const
1412     {
1413 	    if (pAccShapeData && pAccShapeData->pAccShape)
1414         {
1415             pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc);
1416         }
1417     }
1418 };
1419 
1420 void ScChildrenShapes::VisAreaChanged() const
1421 {
1422     ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument);
1423     std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged);
1424 }
1425 
1426 // ============================================================================
1427 
1428 ScAccessibleDocument::ScAccessibleDocument(
1429         const uno::Reference<XAccessible>& rxParent,
1430 		ScTabViewShell* pViewShell,
1431 		ScSplitPos eSplitPos)
1432 	: ScAccessibleDocumentBase(rxParent),
1433 	mpViewShell(pViewShell),
1434 	meSplitPos(eSplitPos),
1435 	mpAccessibleSpreadsheet(NULL),
1436     mpChildrenShapes(NULL),
1437     mpTempAccEdit(NULL),
1438 	mbCompleteSheetSelected(sal_False)
1439 {
1440 	if (pViewShell)
1441     {
1442 		pViewShell->AddAccessibilityObject(*this);
1443 	    Window *pWin = pViewShell->GetWindowByPos(eSplitPos);
1444 	    if( pWin )
1445 	    {
1446 		    pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1447 		    sal_uInt16 nCount =   pWin->GetChildCount();
1448 		    for( sal_uInt16 i=0; i < nCount; ++i )
1449 		    {
1450 			    Window *pChildWin = pWin->GetChild( i );
1451 			    if( pChildWin &&
1452 				    AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1453 				    AddChild( pChildWin->GetAccessible(), sal_False );
1454 		    }
1455 	    }
1456         if (pViewShell->GetViewData()->HasEditView( eSplitPos ))
1457         {
1458             uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewShell->GetViewData()->GetEditView(eSplitPos),
1459                 pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(),
1460                 CellInEditMode);
1461             AddChild(xAcc, sal_False);
1462         }
1463     }
1464     maVisArea = GetVisibleArea_Impl();
1465 }
1466 
1467 void ScAccessibleDocument::Init()
1468 {
1469     if(!mpChildrenShapes)
1470         mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos);
1471 }
1472 
1473 ScAccessibleDocument::~ScAccessibleDocument(void)
1474 {
1475 	if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
1476 	{
1477 		// increment refcount to prevent double call off dtor
1478 		osl_incrementInterlockedCount( &m_refCount );
1479 		dispose();
1480 	}
1481 }
1482 
1483 void SAL_CALL ScAccessibleDocument::disposing()
1484 {
1485     ScUnoGuard aGuard;
1486 	FreeAccessibleSpreadsheet();
1487 	if (mpViewShell)
1488 	{
1489         Window *pWin = mpViewShell->GetWindowByPos(meSplitPos);
1490 	    if( pWin )
1491 		    pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1492 
1493         mpViewShell->RemoveAccessibilityObject(*this);
1494 		mpViewShell = NULL;
1495 	}
1496     if (mpChildrenShapes)
1497         DELETEZ(mpChildrenShapes);
1498 
1499 	ScAccessibleDocumentBase::disposing();
1500 }
1501 
1502 void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ )
1503 		throw (uno::RuntimeException)
1504 {
1505 	disposing();
1506 }
1507 
1508 	//=====  SfxListener  =====================================================
1509 
1510 IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
1511 {
1512 	DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
1513 	if ( pEvent && pEvent->ISA( VclWindowEvent ) )
1514 	{
1515 		VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
1516 		DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
1517 		switch ( pVclEvent->GetId() )
1518 		{
1519         case VCLEVENT_WINDOW_SHOW:  // send create on show for direct accessible children
1520 			{
1521 				Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
1522 				if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1523 				{
1524 					AddChild( pChildWin->GetAccessible(), sal_True );
1525 				}
1526 			}
1527 			break;
1528         case VCLEVENT_WINDOW_HIDE:  // send destroy on hide for direct accessible children
1529 			{
1530 				Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
1531 				if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1532 				{
1533 					RemoveChild( pChildWin->GetAccessible(), sal_True );
1534 				}
1535 			}
1536 			break;
1537 		}
1538 	}
1539 	return 0;
1540 }
1541 
1542 void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1543 {
1544 	if (rHint.ISA( ScAccGridWinFocusLostHint ) )
1545 	{
1546 		const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint;
1547 		if (rRef.GetOldGridWin() == meSplitPos)
1548         {
1549             if (mxTempAcc.is() && mpTempAccEdit)
1550                 mpTempAccEdit->LostFocus();
1551             else if (mpAccessibleSpreadsheet)
1552                 mpAccessibleSpreadsheet->LostFocus();
1553             else
1554                 CommitFocusLost();
1555         }
1556 	}
1557     else if (rHint.ISA( ScAccGridWinFocusGotHint ) )
1558 	{
1559 		const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint;
1560 		if (rRef.GetNewGridWin() == meSplitPos)
1561         {
1562 //IAccessibility2 Implementation 2009-----
1563 			uno::Reference<XAccessible> xAccessible;
1564 			if (mpChildrenShapes)
1565 			{
1566 				sal_Bool bTabMarked(IsTableSelected());
1567 				xAccessible = mpChildrenShapes->GetSelected(0, bTabMarked);
1568 			}
1569 			if( xAccessible.is() )
1570 			{
1571 				uno::Any aNewValue;
1572 				aNewValue<<=AccessibleStateType::FOCUSED;
1573 				static_cast< ::accessibility::AccessibleShape* >(xAccessible.get())->
1574 					CommitChange(AccessibleEventId::STATE_CHANGED,
1575 								aNewValue,
1576 								uno::Any() );
1577 			}
1578 			else
1579 			{
1580             if (mxTempAcc.is() && mpTempAccEdit)
1581                 mpTempAccEdit->GotFocus();
1582             else if (mpAccessibleSpreadsheet)
1583                 mpAccessibleSpreadsheet->GotFocus();
1584             else
1585                 CommitFocusGained();
1586 			}
1587 //-----IAccessibility2 Implementation 2009
1588         }
1589 	}
1590 	else if (rHint.ISA( SfxSimpleHint ))
1591 	{
1592 		const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
1593 		// only notify if child exist, otherwise it is not necessary
1594 		if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
1595 			mpAccessibleSpreadsheet)
1596 		{
1597 			FreeAccessibleSpreadsheet();
1598             if (mpChildrenShapes)
1599                 DELETEZ(mpChildrenShapes);
1600 
1601             // #124567# Accessibility: Shapes / form controls after reload not accessible
1602             if ( !mpChildrenShapes )
1603             {
1604                 mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos );
1605             }
1606 //IAccessibility2 Implementation 2009-----
1607 			//Invoke Init() to rebuild the mpChildrenShapes variable
1608 			this->Init();
1609 //-----IAccessibility2 Implementation 2009
1610 			AccessibleEventObject aEvent;
1611 			aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN;
1612 			aEvent.Source = uno::Reference< XAccessibleContext >(this);
1613 			CommitChange(aEvent); // all childs changed
1614 //IAccessibility2 Implementation 2009-----
1615 			if (mpAccessibleSpreadsheet)
1616 				mpAccessibleSpreadsheet->FireFirstCellFocus();
1617 //-----IAccessibility2 Implementation 2009
1618 		}
1619         else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
1620         {
1621             if (mpChildrenShapes)
1622                 mpChildrenShapes->SetDrawBroadcaster();
1623         }
1624         else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell
1625         {
1626             if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos))
1627             {
1628 				//IAccessibility2 Implementation 2009------
1629 				EditEngine* pEditEng = mpViewShell->GetViewData()->GetEditView(meSplitPos)->GetEditEngine();
1630 				if (pEditEng && pEditEng->GetUpdateMode())
1631 				{
1632 					mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos),
1633 						mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(),
1634 						rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), CellInEditMode);
1635 					uno::Reference<XAccessible> xAcc = mpTempAccEdit;
1636 
1637 					AddChild(xAcc, sal_True);
1638 
1639 					if (mpAccessibleSpreadsheet)
1640 						mpAccessibleSpreadsheet->LostFocus();
1641 					else
1642 						CommitFocusLost();
1643 
1644 					mpTempAccEdit->GotFocus();
1645 				}
1646 				//------IAccessibility2 Implementation 2009
1647             }
1648         }
1649         else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE)
1650         {
1651             if (mxTempAcc.is())
1652             {
1653                 if (mpTempAccEdit)
1654                     mpTempAccEdit->LostFocus();
1655 
1656                 mpTempAccEdit = NULL;
1657                 RemoveChild(mxTempAcc, sal_True);
1658 //IAccessibility2 Implementation 2009-----
1659                 //if (mpAccessibleSpreadsheet)
1660                 if (mpAccessibleSpreadsheet && mpViewShell->IsActive())
1661 //-----IAccessibility2 Implementation 2009
1662                     mpAccessibleSpreadsheet->GotFocus();
1663 //IAccessibility2 Implementation 2009-----
1664                 //else
1665                 else if( mpViewShell->IsActive())
1666 //-----IAccessibility2 Implementation 2009
1667                     CommitFocusGained();
1668             }
1669         }
1670         else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED))
1671         {
1672             Rectangle aOldVisArea(maVisArea);
1673             maVisArea = GetVisibleArea_Impl();
1674 
1675             if (maVisArea != aOldVisArea)
1676             {
1677                 if (maVisArea.GetSize() != aOldVisArea.GetSize())
1678                 {
1679 			        AccessibleEventObject aEvent;
1680 			        aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
1681 			        aEvent.Source = uno::Reference< XAccessibleContext >(this);
1682 
1683 			        CommitChange(aEvent);
1684 
1685                     if (mpAccessibleSpreadsheet)
1686                         mpAccessibleSpreadsheet->BoundingBoxChanged();
1687                 }
1688                 else if (mpAccessibleSpreadsheet)
1689                 {
1690                     mpAccessibleSpreadsheet->VisAreaChanged();
1691                 }
1692                 if (mpChildrenShapes)
1693                     mpChildrenShapes->VisAreaChanged();
1694             }
1695         }
1696 	}
1697 
1698 	ScAccessibleDocumentBase::Notify(rBC, rHint);
1699 }
1700 
1701 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
1702 		throw (uno::RuntimeException)
1703 {
1704 	sal_Bool bSelectionChanged(sal_False);
1705 	if (mpAccessibleSpreadsheet)
1706 	{
1707 		sal_Bool bOldSelected(mbCompleteSheetSelected);
1708 		mbCompleteSheetSelected = IsTableSelected();
1709 		if (bOldSelected != mbCompleteSheetSelected)
1710 		{
1711 			mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
1712 			bSelectionChanged = sal_True;
1713 		}
1714 	}
1715 
1716     if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
1717         bSelectionChanged = sal_True;
1718 
1719 	if (bSelectionChanged)
1720 	{
1721 		AccessibleEventObject aEvent;
1722 		aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1723 		aEvent.Source = uno::Reference< XAccessibleContext >(this);
1724 
1725 		CommitChange(aEvent);
1726 	}
1727 //IAccessibility2 Implementation 2009-----
1728     if(mpChildrenShapes )
1729 	{
1730 		mpChildrenShapes->SelectionChanged();
1731 	}
1732 //-----IAccessibility2 Implementation 2009
1733 }
1734 
1735 	//=====  XInterface  =====================================================
1736 
1737 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
1738 	throw (uno::RuntimeException)
1739 {
1740 //IAccessibility2 Implementation 2009-----
1741 	uno::Any aAnyTmp;
1742 	if(rType == ::getCppuType((com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> *)NULL) )
1743        {
1744 	     com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> AccFromXShape = this;
1745             aAnyTmp <<= AccFromXShape;
1746 	     return aAnyTmp;
1747        }
1748 //-----IAccessibility2 Implementation 2009
1749 	uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
1750 	return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
1751 }
1752 
1753 void SAL_CALL ScAccessibleDocument::acquire()
1754 	throw ()
1755 {
1756 	ScAccessibleContextBase::acquire();
1757 }
1758 
1759 void SAL_CALL ScAccessibleDocument::release()
1760 	throw ()
1761 {
1762 	ScAccessibleContextBase::release();
1763 }
1764 
1765 	//=====  XAccessibleComponent  ============================================
1766 
1767 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint(
1768 		const awt::Point& rPoint )
1769 		throw (uno::RuntimeException)
1770 {
1771 	uno::Reference<XAccessible> xAccessible = NULL;
1772     if (containsPoint(rPoint))
1773     {
1774     	ScUnoGuard aGuard;
1775         IsObjectValid();
1776         if (mpChildrenShapes)
1777             xAccessible = mpChildrenShapes->GetAt(rPoint);
1778 	    if(!xAccessible.is())
1779         {
1780             if (mxTempAcc.is())
1781             {
1782                 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext());
1783                 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY);
1784                 if (xComp.is())
1785                 {
1786                     Rectangle aBound(VCLRectangle(xComp->getBounds()));
1787                     if (aBound.IsInside(VCLPoint(rPoint)))
1788                         xAccessible = mxTempAcc;
1789                 }
1790             }
1791             if (!xAccessible.is())
1792 		        xAccessible = GetAccessibleSpreadsheet();
1793         }
1794     }
1795 	return xAccessible;
1796 }
1797 
1798 void SAL_CALL ScAccessibleDocument::grabFocus(  )
1799 		throw (uno::RuntimeException)
1800 {
1801 	ScUnoGuard aGuard;
1802     IsObjectValid();
1803 	if (getAccessibleParent().is())
1804 	{
1805 		uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1806 		if (xAccessibleComponent.is())
1807 		{
1808 			xAccessibleComponent->grabFocus();
1809 			// grab only focus if it does not have the focus and it is not hidden
1810 			if (mpViewShell && mpViewShell->GetViewData() &&
1811 				(mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
1812 				mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
1813 			{
1814 				mpViewShell->ActivatePart(meSplitPos);
1815 			}
1816 		}
1817 	}
1818 }
1819 
1820 	//=====  XAccessibleContext  ==============================================
1821 
1822     ///	Return the number of currently visible children.
1823 sal_Int32 SAL_CALL
1824     ScAccessibleDocument::getAccessibleChildCount(void)
1825     throw (uno::RuntimeException)
1826 {
1827 	ScUnoGuard aGuard;
1828     IsObjectValid();
1829     sal_Int32 nCount(1);
1830     if (mpChildrenShapes)
1831         nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
1832 
1833     if (mxTempAcc.is())
1834         ++nCount;
1835 
1836 	return nCount;
1837 }
1838 
1839     ///	Return the specified child or NULL if index is invalid.
1840 uno::Reference<XAccessible> SAL_CALL
1841     ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex)
1842     throw (uno::RuntimeException,
1843 		lang::IndexOutOfBoundsException)
1844 {
1845 	ScUnoGuard aGuard;
1846     IsObjectValid();
1847 	uno::Reference<XAccessible> xAccessible;
1848 	if (nIndex >= 0)
1849 	{
1850         sal_Int32 nCount(1);
1851         if (mpChildrenShapes)
1852         {
1853             xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
1854             nCount = mpChildrenShapes->GetCount(); //there is always a table
1855         }
1856         if (!xAccessible.is())
1857         {
1858             if (nIndex < nCount)
1859                 xAccessible = GetAccessibleSpreadsheet();
1860             else if (nIndex == nCount && mxTempAcc.is())
1861                 xAccessible = mxTempAcc;
1862         }
1863 	}
1864 
1865     if (!xAccessible.is())
1866         throw lang::IndexOutOfBoundsException();
1867 
1868 	return xAccessible;
1869 }
1870 
1871     ///	Return the set of current states.
1872 uno::Reference<XAccessibleStateSet> SAL_CALL
1873     ScAccessibleDocument::getAccessibleStateSet(void)
1874     throw (uno::RuntimeException)
1875 {
1876 	ScUnoGuard aGuard;
1877 	uno::Reference<XAccessibleStateSet> xParentStates;
1878 	if (getAccessibleParent().is())
1879 	{
1880 		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1881 		xParentStates = xParentContext->getAccessibleStateSet();
1882 	}
1883 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1884 	if (IsDefunc(xParentStates))
1885 		pStateSet->AddState(AccessibleStateType::DEFUNC);
1886     else
1887     {
1888 	    if (IsEditable(xParentStates))
1889 		    pStateSet->AddState(AccessibleStateType::EDITABLE);
1890 	    pStateSet->AddState(AccessibleStateType::ENABLED);
1891 	    pStateSet->AddState(AccessibleStateType::OPAQUE);
1892 	    if (isShowing())
1893 		    pStateSet->AddState(AccessibleStateType::SHOWING);
1894 	    if (isVisible())
1895 		    pStateSet->AddState(AccessibleStateType::VISIBLE);
1896     }
1897 	return pStateSet;
1898 }
1899 
1900 //IAccessibility2 Implementation 2009-----
1901 ::rtl::OUString SAL_CALL
1902     ScAccessibleDocument::getAccessibleName(void)
1903     throw (::com::sun::star::uno::RuntimeException)
1904 {
1905 	rtl::OUString sName = String(ScResId(STR_ACC_DOC_SPREADSHEET));
1906 	ScDocument* pScDoc = GetDocument();
1907 	if ( pScDoc )
1908 	{
1909 		rtl::OUString sFileName = pScDoc->getDocAccTitle();
1910 		if ( !sFileName.getLength() )
1911 		{
1912 			SfxObjectShell* pObjSh = pScDoc->GetDocumentShell();
1913 			if ( pObjSh )
1914 			{
1915 				sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME );
1916 			}
1917 		}
1918 		rtl::OUString sReadOnly;
1919 		if (pScDoc->getDocReadOnly())
1920 		{
1921 			sReadOnly = String(ScResId(STR_ACC_DOC_SPREADSHEET_READONLY));
1922 		}
1923 		if ( sFileName.getLength() )
1924 		{
1925 			sName = sFileName + sReadOnly + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName;
1926 		}
1927 	}
1928 	return sName;
1929 }
1930 //-----IAccessibility2 Implementation 2009
1931 	///=====  XAccessibleSelection  ===========================================
1932 
1933 void SAL_CALL
1934 	ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
1935 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1936 {
1937 	ScUnoGuard aGuard;
1938     IsObjectValid();
1939 
1940     if (mpChildrenShapes)
1941     {
1942         sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1943         if (mxTempAcc.is())
1944             ++nCount;
1945         if (nChildIndex < 0 || nChildIndex >= nCount)
1946             throw lang::IndexOutOfBoundsException();
1947 
1948         uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1949         if (xAccessible.is())
1950         {
1951 		    sal_Bool bWasTableSelected(IsTableSelected());
1952 
1953             if (mpChildrenShapes)
1954                 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1955 
1956 		    if (bWasTableSelected)
1957 			    mpViewShell->SelectAll();
1958         }
1959         else
1960         {
1961 		    if (mpViewShell)
1962 			    mpViewShell->SelectAll();
1963         }
1964     }
1965 }
1966 
1967 sal_Bool SAL_CALL
1968 	ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
1969 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1970 {
1971 	ScUnoGuard aGuard;
1972     IsObjectValid();
1973 	sal_Bool bResult(sal_False);
1974 
1975     if (mpChildrenShapes)
1976     {
1977         sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1978         if (mxTempAcc.is())
1979             ++nCount;
1980         if (nChildIndex < 0 || nChildIndex >= nCount)
1981             throw lang::IndexOutOfBoundsException();
1982 
1983         uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1984         if (xAccessible.is())
1985         {
1986 		    uno::Reference<drawing::XShape> xShape;
1987 		    bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high
1988         }
1989         else
1990         {
1991             if (mxTempAcc.is() && nChildIndex == nCount)
1992                 bResult = sal_True;
1993             else
1994     		    bResult = IsTableSelected();
1995         }
1996     }
1997 	return bResult;
1998 }
1999 
2000 void SAL_CALL
2001 	ScAccessibleDocument::clearAccessibleSelection(  )
2002 		throw (uno::RuntimeException)
2003 {
2004 	ScUnoGuard aGuard;
2005     IsObjectValid();
2006 
2007     if (mpChildrenShapes)
2008         mpChildrenShapes->DeselectAll(); //deselects all (also the table)
2009 }
2010 
2011 void SAL_CALL
2012 	ScAccessibleDocument::selectAllAccessibleChildren(  )
2013 		throw (uno::RuntimeException)
2014 {
2015 	ScUnoGuard aGuard;
2016     IsObjectValid();
2017 
2018     if (mpChildrenShapes)
2019         mpChildrenShapes->SelectAll();
2020 
2021 	// select table after shapes, because while selecting shapes the table will be deselected
2022 	if (mpViewShell)
2023 	{
2024 		mpViewShell->SelectAll();
2025 	}
2026 }
2027 
2028 sal_Int32 SAL_CALL
2029 	ScAccessibleDocument::getSelectedAccessibleChildCount(  )
2030 		throw (uno::RuntimeException)
2031 {
2032 	ScUnoGuard aGuard;
2033     IsObjectValid();
2034 	sal_Int32 nCount(0);
2035 
2036     if (mpChildrenShapes)
2037         nCount = mpChildrenShapes->GetSelectedCount();
2038 
2039 	if (IsTableSelected())
2040 		++nCount;
2041 
2042     if (mxTempAcc.is())
2043         ++nCount;
2044 
2045 	return nCount;
2046 }
2047 
2048 uno::Reference<XAccessible > SAL_CALL
2049 	ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
2050 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2051 {
2052 	ScUnoGuard aGuard;
2053     IsObjectValid();
2054 	uno::Reference<XAccessible> xAccessible;
2055     if (mpChildrenShapes)
2056     {
2057         sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
2058         if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
2059             throw lang::IndexOutOfBoundsException();
2060 
2061         sal_Bool bTabMarked(IsTableSelected());
2062 
2063         if (mpChildrenShapes)
2064             xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
2065         if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
2066             xAccessible = mxTempAcc;
2067         else if (bTabMarked)
2068             xAccessible = GetAccessibleSpreadsheet();
2069     }
2070 
2071     DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed");
2072 
2073 	return xAccessible;
2074 }
2075 
2076 void SAL_CALL
2077 	ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
2078 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2079 {
2080 	ScUnoGuard aGuard;
2081     IsObjectValid();
2082 
2083     if (mpChildrenShapes)
2084     {
2085         sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
2086         if (mxTempAcc.is())
2087             ++nCount;
2088         if (nChildIndex < 0 || nChildIndex >= nCount)
2089             throw lang::IndexOutOfBoundsException();
2090 
2091         sal_Bool bTabMarked(IsTableSelected());
2092 
2093         uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
2094         if (xAccessible.is())
2095         {
2096             if (mpChildrenShapes)
2097                 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
2098 
2099 		    if (bTabMarked)
2100 			    mpViewShell->SelectAll(); // select the table again
2101         }
2102         else if (bTabMarked)
2103             mpViewShell->Unmark();
2104     }
2105 }
2106 
2107 	//=====  XServiceInfo  ====================================================
2108 
2109 ::rtl::OUString SAL_CALL
2110     ScAccessibleDocument::getImplementationName(void)
2111     throw (uno::RuntimeException)
2112 {
2113 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
2114 }
2115 
2116 uno::Sequence< ::rtl::OUString> SAL_CALL
2117 	ScAccessibleDocument::getSupportedServiceNames(void)
2118         throw (uno::RuntimeException)
2119 {
2120 	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
2121     sal_Int32 nOldSize(aSequence.getLength());
2122     aSequence.realloc(nOldSize + 1);
2123     ::rtl::OUString* pNames = aSequence.getArray();
2124 
2125 	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView"));
2126 
2127 	return aSequence;
2128 }
2129 
2130 //=====  XTypeProvider  =======================================================
2131 
2132 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
2133 		throw (uno::RuntimeException)
2134 {
2135 	return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
2136 }
2137 
2138 uno::Sequence<sal_Int8> SAL_CALL
2139 	ScAccessibleDocument::getImplementationId(void)
2140     throw (uno::RuntimeException)
2141 {
2142     ScUnoGuard aGuard;
2143     IsObjectValid();
2144 	static uno::Sequence<sal_Int8> aId;
2145 	if (aId.getLength() == 0)
2146 	{
2147 		aId.realloc (16);
2148 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
2149 	}
2150 	return aId;
2151 }
2152 
2153 ///=====  IAccessibleViewForwarder  ========================================
2154 
2155 sal_Bool ScAccessibleDocument::IsValid (void) const
2156 {
2157     ScUnoGuard aGuard;
2158     IsObjectValid();
2159     return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
2160 }
2161 
2162 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
2163 {
2164     Rectangle aVisRect(GetBoundingBox());
2165 
2166     Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point
2167     aPoint.setX(-aPoint.getX());
2168     aPoint.setY(-aPoint.getY());
2169     aVisRect.SetPos(aPoint);
2170 
2171     ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2172     if (pWin)
2173         aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
2174 
2175     return aVisRect;
2176 }
2177 
2178 Rectangle ScAccessibleDocument::GetVisibleArea() const
2179 {
2180     ScUnoGuard aGuard;
2181     IsObjectValid();
2182     return maVisArea;
2183 }
2184 
2185 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
2186 {
2187     ScUnoGuard aGuard;
2188     IsObjectValid();
2189     Point aPoint;
2190     ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2191     if (pWin)
2192     {
2193         aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
2194         aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
2195     }
2196     return aPoint;
2197 }
2198 
2199 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
2200 {
2201     ScUnoGuard aGuard;
2202     IsObjectValid();
2203     Size aSize;
2204     ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2205     if (pWin)
2206         aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
2207     return aSize;
2208 }
2209 
2210 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
2211 {
2212     ScUnoGuard aGuard;
2213     IsObjectValid();
2214     Point aPoint;
2215     ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2216     if (pWin)
2217     {
2218         aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
2219         aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
2220     }
2221     return aPoint;
2222 }
2223 
2224 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
2225 {
2226     ScUnoGuard aGuard;
2227     IsObjectValid();
2228     Size aSize;
2229     ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2230     if (pWin)
2231         aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
2232     return aSize;
2233 }
2234 
2235     //=====  internal  ========================================================
2236 
2237 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
2238 {
2239     utl::AccessibleRelationSetHelper* pRelationSet = NULL;
2240     if (mpChildrenShapes)
2241         pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
2242     return pRelationSet;
2243 }
2244 
2245 ::rtl::OUString SAL_CALL
2246     ScAccessibleDocument::createAccessibleDescription(void)
2247     throw (uno::RuntimeException)
2248 {
2249     rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR));
2250 	return sDescription;
2251 }
2252 
2253 ::rtl::OUString SAL_CALL
2254     ScAccessibleDocument::createAccessibleName(void)
2255     throw (uno::RuntimeException)
2256 {
2257 	ScUnoGuard aGuard;
2258     IsObjectValid();
2259 	rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME));
2260 	sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
2261 	sName += rtl::OUString::valueOf(nNumber);
2262 	return sName;
2263 }
2264 
2265 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
2266 	throw (uno::RuntimeException)
2267 {
2268 	Rectangle aRect;
2269 	if (mpViewShell)
2270 	{
2271 		Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2272 		if (pWindow)
2273 			aRect = pWindow->GetWindowExtentsRelative(NULL);
2274 	}
2275 	return aRect;
2276 }
2277 
2278 Rectangle ScAccessibleDocument::GetBoundingBox() const
2279 	throw (uno::RuntimeException)
2280 {
2281 	Rectangle aRect;
2282 	if (mpViewShell)
2283 	{
2284 		Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2285 		if (pWindow)
2286 			aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
2287 	}
2288 	return aRect;
2289 }
2290 
2291 SCTAB ScAccessibleDocument::getVisibleTable() const
2292 {
2293 	SCTAB nVisibleTable(0);
2294 	if (mpViewShell && mpViewShell->GetViewData())
2295 		nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
2296 	return nVisibleTable;
2297 }
2298 
2299 uno::Reference < XAccessible >
2300 	ScAccessibleDocument::GetAccessibleSpreadsheet()
2301 {
2302 	if (!mpAccessibleSpreadsheet && mpViewShell)
2303 	{
2304 		mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
2305 		mpAccessibleSpreadsheet->acquire();
2306 		mpAccessibleSpreadsheet->Init();
2307 		mbCompleteSheetSelected = IsTableSelected();
2308 	}
2309 	return mpAccessibleSpreadsheet;
2310 }
2311 
2312 void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2313 {
2314 	if (mpAccessibleSpreadsheet)
2315 	{
2316 		mpAccessibleSpreadsheet->dispose();
2317 		mpAccessibleSpreadsheet->release();
2318 		mpAccessibleSpreadsheet = NULL;
2319 	}
2320 }
2321 
2322 sal_Bool ScAccessibleDocument::IsTableSelected() const
2323 {
2324 	sal_Bool bResult (sal_False);
2325 	if(mpViewShell)
2326 	{
2327 		SCTAB nTab(getVisibleTable());
2328         //#103800#; use a copy of MarkData
2329         ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
2330 		aMarkData.MarkToMulti();
2331 		if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
2332 			bResult = sal_True;
2333 	}
2334 	return bResult;
2335 }
2336 
2337 sal_Bool ScAccessibleDocument::IsDefunc(
2338 	const uno::Reference<XAccessibleStateSet>& rxParentStates)
2339 {
2340 	return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
2341 		(rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
2342 }
2343 
2344 sal_Bool ScAccessibleDocument::IsEditable(
2345     const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
2346 {
2347 	// what is with document protection or readonly documents?
2348 	return sal_True;
2349 }
2350 
2351 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2352 {
2353     DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before");
2354     if (xAcc.is())
2355     {
2356         mxTempAcc = xAcc;
2357 		if( bFireEvent )
2358 		{
2359 			AccessibleEventObject aEvent;
2360                         aEvent.Source = uno::Reference<XAccessibleContext>(this);
2361 			aEvent.EventId = AccessibleEventId::CHILD;
2362 			aEvent.NewValue <<= mxTempAcc;
2363 			CommitChange( aEvent );
2364 		}
2365     }
2366 }
2367 
2368 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2369 {
2370     DBG_ASSERT(mxTempAcc.is(), "this object should be added before");
2371     if (xAcc.is())
2372     {
2373         DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
2374 		if( bFireEvent )
2375 		{
2376 			AccessibleEventObject aEvent;
2377                         aEvent.Source = uno::Reference<XAccessibleContext>(this);
2378 			aEvent.EventId = AccessibleEventId::CHILD;
2379 			aEvent.OldValue <<= mxTempAcc;
2380 			CommitChange( aEvent );
2381 		}
2382         mxTempAcc = NULL;
2383     }
2384 }
2385 
2386 rtl::OUString ScAccessibleDocument::GetCurrentCellName() const
2387 {
2388 	String sName( ScResId(STR_ACC_CELL_NAME) );
2389     if (mpViewShell)
2390     {
2391 	    String sAddress;
2392 	    // Document not needed, because only the cell address, but not the tablename is needed
2393 	    mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL );
2394 	    sName.SearchAndReplaceAscii("%1", sAddress);
2395     }
2396     return rtl::OUString(sName);
2397 }
2398 
2399 rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const
2400 {
2401     return rtl::OUString();
2402 }
2403 //IAccessibility2 Implementation 2009-----
2404 ScDocument *ScAccessibleDocument::GetDocument() const
2405 {
2406 	return mpViewShell ? mpViewShell->GetViewData()->GetDocument() : NULL;
2407 }
2408 ScAddress   ScAccessibleDocument::GetCurCellAddress() const
2409 {
2410 	return mpViewShell ? mpViewShell->GetViewData()->GetCurPos() :ScAddress();
2411 }
2412 uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes()
2413 		throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
2414 {
2415 
2416 	uno::Any anyAtrribute;
2417 
2418 	rtl::OUString sName;
2419 	rtl::OUString sValue;
2420 	sal_uInt16 sheetIndex;
2421 	String sSheetName;
2422 	sheetIndex = getVisibleTable();
2423 	if(GetDocument()==NULL)
2424 		return anyAtrribute;
2425 	GetDocument()->GetName(sheetIndex,sSheetName);
2426 	sName = rtl::OUString::createFromAscii("page-name:");
2427 	sValue = sName + sSheetName ;
2428 	sName = rtl::OUString::createFromAscii(";page-number:");
2429 	sValue += sName;
2430 	sValue += String::CreateFromInt32(sheetIndex+1) ;
2431 	sName = rtl::OUString::createFromAscii(";total-pages:");
2432 	sValue += sName;
2433 	sValue += String::CreateFromInt32(GetDocument()->GetTableCount());
2434 	sValue +=  rtl::OUString::createFromAscii(";");
2435 	anyAtrribute <<= sValue;
2436 	return anyAtrribute;
2437 }
2438 com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence()
2439 {
2440 	if ( getAccessibleChildCount() )
2441 	{
2442 		uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table
2443 		if ( xSCTableAcc.is() )
2444 		{
2445 			uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY );
2446 			sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount();
2447 			if( nSelCount )
2448 			{
2449 				uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell
2450 				if ( xSel.is() )
2451 				{
2452 					uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2453 					if ( xSelContext.is() )
2454 					{
2455 						if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL )
2456 						{
2457 							sal_Int32 nParaCount = 0;
2458 							uno::Sequence <uno::Any> aSequence(nSelCount);
2459 							for ( sal_Int32 i = 0; i < nSelCount; i++ )
2460 							{
2461 								xSel = xAccSelection->getSelectedAccessibleChild( i )	;
2462 								if ( xSel.is() )
2463 								{
2464 									xSelContext = xSel->getAccessibleContext();
2465 									if ( xSelContext.is() )
2466 									{
2467 										if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL )
2468 										{
2469 											aSequence[nParaCount] = uno::makeAny( xSel );
2470 											nParaCount++;
2471 										}
2472 									}
2473 								}
2474 							}
2475 							return aSequence;
2476 						}
2477 					}
2478 				}
2479 			}
2480 		}
2481 	}
2482 	uno::Sequence <uno::Any> aEmpty;
2483 	return aEmpty;
2484 }
2485 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
2486 		SAL_CALL ScAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
2487 		throw ( ::com::sun::star::uno::RuntimeException )
2488 {
2489 	const sal_Int32 SPELLCHECKFLOWTO = 1;
2490 	const sal_Int32 FINDREPLACEFLOWTO = 2;
2491 	if ( nType == SPELLCHECKFLOWTO )
2492 	{
2493 		uno::Reference< ::com::sun::star::drawing::XShape > xShape;
2494 		rAny >>= xShape;
2495 		if ( xShape.is() )
2496 		{
2497 			uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape);
2498 			uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
2499 			if ( xAccSelection.is() )
2500 			{
2501 				if ( xAccSelection->getSelectedAccessibleChildCount() )
2502 				{
2503 					uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
2504 					if ( xSel.is() )
2505 					{
2506 						uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2507 						if ( xSelContext.is() )
2508 						{
2509 							//if in sw we find the selected paragraph here
2510 							if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
2511 							{
2512 								uno::Sequence<uno::Any> aRet( 1 );
2513 								aRet[0] = uno::makeAny( xSel );
2514 								return aRet;
2515 							}
2516 						}
2517 					}
2518 				}
2519 			}
2520 		}
2521 		else
2522 		{
2523 			if ( getSelectedAccessibleChildCount() )
2524 			{
2525 				uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 );
2526 				if ( xSel.is() )
2527 				{
2528 					uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2529 					if ( xSelContext.is() )
2530 					{
2531 						uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY );
2532 						if ( xAccChildSelection.is() )
2533 						{
2534 							if ( xAccChildSelection->getSelectedAccessibleChildCount() )
2535 							{
2536 								uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 );
2537 								if ( xChildSel.is() )
2538 								{
2539 									uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() );
2540 									if ( xChildSelContext.is() &&
2541 										xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH )
2542 									{
2543 										uno::Sequence<uno::Any> aRet( 1 );
2544 										aRet[0] = uno::makeAny( xChildSel );
2545 										return aRet;
2546 									}
2547 								}
2548 							}
2549 						}
2550 					}
2551 				}
2552 			}
2553 		}
2554 	}
2555 	else if ( nType == FINDREPLACEFLOWTO )
2556 	{
2557 		sal_Bool bSuccess(sal_False);
2558 		rAny >>= bSuccess;
2559 		if ( bSuccess )
2560 		{
2561 			uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence();
2562 			if ( aSeq.getLength() )
2563 			{
2564 				return aSeq;
2565 			}
2566 			else if( mpAccessibleSpreadsheet )
2567 			{
2568 				uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell();
2569 				// add xFindCellAcc to the return the Sequence
2570 				uno::Sequence< uno::Any> aSeq2(1);
2571 				aSeq2[0] = uno::makeAny( xFindCellAcc );
2572 				return aSeq2;
2573 			}
2574 		}
2575 	}
2576 	uno::Sequence< uno::Any> aEmpty;
2577 	return aEmpty;
2578 }
2579 void ScAccessibleDocument::SwitchViewFireFocus()
2580 {
2581 	if (mpAccessibleSpreadsheet)
2582 	{
2583 		mpAccessibleSpreadsheet->FireFirstCellFocus();
2584 	}
2585 }
2586 
2587 sal_Int32 SAL_CALL ScAccessibleDocument::getForeground(  )
2588         throw (uno::RuntimeException)
2589 {
2590     return COL_BLACK;
2591 }
2592 
2593 sal_Int32 SAL_CALL ScAccessibleDocument::getBackground(  )
2594         throw (uno::RuntimeException)
2595 {
2596 	ScUnoGuard aGuard;
2597     IsObjectValid();
2598     return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
2599 }
2600 //-----IAccessibility2 Implementation 2009
2601 
2602