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