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