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