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