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 really 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 if (mpAccessibleSpreadsheet && mpViewShell->IsActive())
1655 mpAccessibleSpreadsheet->FireFirstCellFocus();
1656 }
1657 else if (mpAccessibleSpreadsheet)
1658 {
1659 mpAccessibleSpreadsheet->VisAreaChanged();
1660 }
1661 if (mpChildrenShapes)
1662 mpChildrenShapes->VisAreaChanged();
1663 }
1664 }
1665 }
1666
1667 ScAccessibleDocumentBase::Notify(rBC, rHint);
1668 }
1669
selectionChanged(const lang::EventObject &)1670 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
1671 throw (uno::RuntimeException)
1672 {
1673 sal_Bool bSelectionChanged(sal_False);
1674 if (mpAccessibleSpreadsheet)
1675 {
1676 sal_Bool bOldSelected(mbCompleteSheetSelected);
1677 mbCompleteSheetSelected = IsTableSelected();
1678 if (bOldSelected != mbCompleteSheetSelected)
1679 {
1680 mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
1681 bSelectionChanged = sal_True;
1682 }
1683 }
1684
1685 if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
1686 bSelectionChanged = sal_True;
1687
1688 if (bSelectionChanged)
1689 {
1690 AccessibleEventObject aEvent;
1691 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1692 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1693
1694 CommitChange(aEvent);
1695 }
1696 if(mpChildrenShapes )
1697 {
1698 mpChildrenShapes->SelectionChanged();
1699 }
1700 }
1701
1702 //===== XInterface =====================================================
1703
queryInterface(uno::Type const & rType)1704 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
1705 throw (uno::RuntimeException)
1706 {
1707 uno::Any aAnyTmp;
1708 if(rType == ::getCppuType((com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> *)NULL) )
1709 {
1710 com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> AccFromXShape = this;
1711 aAnyTmp <<= AccFromXShape;
1712 return aAnyTmp;
1713 }
1714 uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
1715 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
1716 }
1717
acquire()1718 void SAL_CALL ScAccessibleDocument::acquire()
1719 throw ()
1720 {
1721 ScAccessibleContextBase::acquire();
1722 }
1723
release()1724 void SAL_CALL ScAccessibleDocument::release()
1725 throw ()
1726 {
1727 ScAccessibleContextBase::release();
1728 }
1729
1730 //===== XAccessibleComponent ============================================
1731
getAccessibleAtPoint(const awt::Point & rPoint)1732 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint(
1733 const awt::Point& rPoint )
1734 throw (uno::RuntimeException)
1735 {
1736 uno::Reference<XAccessible> xAccessible = NULL;
1737 if (containsPoint(rPoint))
1738 {
1739 ScUnoGuard aGuard;
1740 IsObjectValid();
1741 if (mpChildrenShapes)
1742 xAccessible = mpChildrenShapes->GetAt(rPoint);
1743 if(!xAccessible.is())
1744 {
1745 if (mxTempAcc.is())
1746 {
1747 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext());
1748 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY);
1749 if (xComp.is())
1750 {
1751 Rectangle aBound(VCLRectangle(xComp->getBounds()));
1752 if (aBound.IsInside(VCLPoint(rPoint)))
1753 xAccessible = mxTempAcc;
1754 }
1755 }
1756 if (!xAccessible.is())
1757 xAccessible = GetAccessibleSpreadsheet();
1758 }
1759 }
1760 return xAccessible;
1761 }
1762
grabFocus()1763 void SAL_CALL ScAccessibleDocument::grabFocus( )
1764 throw (uno::RuntimeException)
1765 {
1766 ScUnoGuard aGuard;
1767 IsObjectValid();
1768 if (getAccessibleParent().is())
1769 {
1770 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1771 if (xAccessibleComponent.is())
1772 {
1773 xAccessibleComponent->grabFocus();
1774 // grab only focus if it does not have the focus and it is not hidden
1775 if (mpViewShell && mpViewShell->GetViewData() &&
1776 (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
1777 mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
1778 {
1779 mpViewShell->ActivatePart(meSplitPos);
1780 }
1781 }
1782 }
1783 }
1784
1785 //===== XAccessibleContext ==============================================
1786
1787 /// Return the number of currently visible children.
1788 sal_Int32 SAL_CALL
getAccessibleChildCount(void)1789 ScAccessibleDocument::getAccessibleChildCount(void)
1790 throw (uno::RuntimeException)
1791 {
1792 ScUnoGuard aGuard;
1793 IsObjectValid();
1794 sal_Int32 nCount(1);
1795 if (mpChildrenShapes)
1796 nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
1797
1798 if (mxTempAcc.is())
1799 ++nCount;
1800
1801 return nCount;
1802 }
1803
1804 /// Return the specified child or NULL if index is invalid.
1805 uno::Reference<XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)1806 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex)
1807 throw (uno::RuntimeException,
1808 lang::IndexOutOfBoundsException)
1809 {
1810 ScUnoGuard aGuard;
1811 IsObjectValid();
1812 uno::Reference<XAccessible> xAccessible;
1813 if (nIndex >= 0)
1814 {
1815 sal_Int32 nCount(1);
1816 if (mpChildrenShapes)
1817 {
1818 xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
1819 nCount = mpChildrenShapes->GetCount(); //there is always a table
1820 }
1821 if (!xAccessible.is())
1822 {
1823 if (nIndex < nCount)
1824 xAccessible = GetAccessibleSpreadsheet();
1825 else if (nIndex == nCount && mxTempAcc.is())
1826 xAccessible = mxTempAcc;
1827 }
1828 }
1829
1830 if (!xAccessible.is())
1831 throw lang::IndexOutOfBoundsException();
1832
1833 return xAccessible;
1834 }
1835
1836 /// Return the set of current states.
1837 uno::Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)1838 ScAccessibleDocument::getAccessibleStateSet(void)
1839 throw (uno::RuntimeException)
1840 {
1841 ScUnoGuard aGuard;
1842 uno::Reference<XAccessibleStateSet> xParentStates;
1843 if (getAccessibleParent().is())
1844 {
1845 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1846 xParentStates = xParentContext->getAccessibleStateSet();
1847 }
1848 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1849 if (IsDefunc(xParentStates))
1850 pStateSet->AddState(AccessibleStateType::DEFUNC);
1851 else
1852 {
1853 if (IsEditable(xParentStates))
1854 pStateSet->AddState(AccessibleStateType::EDITABLE);
1855 pStateSet->AddState(AccessibleStateType::ENABLED);
1856 pStateSet->AddState(AccessibleStateType::OPAQUE);
1857 if (isShowing())
1858 pStateSet->AddState(AccessibleStateType::SHOWING);
1859 if (isVisible())
1860 pStateSet->AddState(AccessibleStateType::VISIBLE);
1861 }
1862 return pStateSet;
1863 }
1864
1865 ::rtl::OUString SAL_CALL
getAccessibleName(void)1866 ScAccessibleDocument::getAccessibleName(void)
1867 throw (::com::sun::star::uno::RuntimeException)
1868 {
1869 rtl::OUString sName = String(ScResId(STR_ACC_DOC_SPREADSHEET));
1870 ScDocument* pScDoc = GetDocument();
1871 if ( pScDoc )
1872 {
1873 rtl::OUString sFileName = pScDoc->getDocAccTitle();
1874 if ( !sFileName.getLength() )
1875 {
1876 SfxObjectShell* pObjSh = pScDoc->GetDocumentShell();
1877 if ( pObjSh )
1878 {
1879 sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME );
1880 }
1881 }
1882 rtl::OUString sReadOnly;
1883 if (pScDoc->getDocReadOnly())
1884 {
1885 sReadOnly = String(ScResId(STR_ACC_DOC_SPREADSHEET_READONLY));
1886 }
1887 if ( sFileName.getLength() )
1888 {
1889 sName = sFileName + sReadOnly + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName;
1890 }
1891 }
1892 return sName;
1893 }
1894 ///===== XAccessibleSelection ===========================================
1895
1896 void SAL_CALL
selectAccessibleChild(sal_Int32 nChildIndex)1897 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
1898 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1899 {
1900 ScUnoGuard aGuard;
1901 IsObjectValid();
1902
1903 if (mpChildrenShapes)
1904 {
1905 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1906 if (mxTempAcc.is())
1907 ++nCount;
1908 if (nChildIndex < 0 || nChildIndex >= nCount)
1909 throw lang::IndexOutOfBoundsException();
1910
1911 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1912 if (xAccessible.is())
1913 {
1914 sal_Bool bWasTableSelected(IsTableSelected());
1915
1916 if (mpChildrenShapes)
1917 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1918
1919 if (bWasTableSelected)
1920 mpViewShell->SelectAll();
1921 }
1922 else
1923 {
1924 if (mpViewShell)
1925 mpViewShell->SelectAll();
1926 }
1927 }
1928 }
1929
1930 sal_Bool SAL_CALL
isAccessibleChildSelected(sal_Int32 nChildIndex)1931 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
1932 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1933 {
1934 ScUnoGuard aGuard;
1935 IsObjectValid();
1936 sal_Bool bResult(sal_False);
1937
1938 if (mpChildrenShapes)
1939 {
1940 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1941 if (mxTempAcc.is())
1942 ++nCount;
1943 if (nChildIndex < 0 || nChildIndex >= nCount)
1944 throw lang::IndexOutOfBoundsException();
1945
1946 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1947 if (xAccessible.is())
1948 {
1949 uno::Reference<drawing::XShape> xShape;
1950 bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high
1951 }
1952 else
1953 {
1954 if (mxTempAcc.is() && nChildIndex == nCount)
1955 bResult = sal_True;
1956 else
1957 bResult = IsTableSelected();
1958 }
1959 }
1960 return bResult;
1961 }
1962
1963 void SAL_CALL
clearAccessibleSelection()1964 ScAccessibleDocument::clearAccessibleSelection( )
1965 throw (uno::RuntimeException)
1966 {
1967 ScUnoGuard aGuard;
1968 IsObjectValid();
1969
1970 if (mpChildrenShapes)
1971 mpChildrenShapes->DeselectAll(); //deselects all (also the table)
1972 }
1973
1974 void SAL_CALL
selectAllAccessibleChildren()1975 ScAccessibleDocument::selectAllAccessibleChildren( )
1976 throw (uno::RuntimeException)
1977 {
1978 ScUnoGuard aGuard;
1979 IsObjectValid();
1980
1981 if (mpChildrenShapes)
1982 mpChildrenShapes->SelectAll();
1983
1984 // select table after shapes, because while selecting shapes the table will be deselected
1985 if (mpViewShell)
1986 {
1987 mpViewShell->SelectAll();
1988 }
1989 }
1990
1991 sal_Int32 SAL_CALL
getSelectedAccessibleChildCount()1992 ScAccessibleDocument::getSelectedAccessibleChildCount( )
1993 throw (uno::RuntimeException)
1994 {
1995 ScUnoGuard aGuard;
1996 IsObjectValid();
1997 sal_Int32 nCount(0);
1998
1999 if (mpChildrenShapes)
2000 nCount = mpChildrenShapes->GetSelectedCount();
2001
2002 if (IsTableSelected())
2003 ++nCount;
2004
2005 if (mxTempAcc.is())
2006 ++nCount;
2007
2008 return nCount;
2009 }
2010
2011 uno::Reference<XAccessible > SAL_CALL
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)2012 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
2013 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2014 {
2015 ScUnoGuard aGuard;
2016 IsObjectValid();
2017 uno::Reference<XAccessible> xAccessible;
2018 if (mpChildrenShapes)
2019 {
2020 sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
2021 if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
2022 throw lang::IndexOutOfBoundsException();
2023
2024 sal_Bool bTabMarked(IsTableSelected());
2025
2026 if (mpChildrenShapes)
2027 xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
2028 if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
2029 xAccessible = mxTempAcc;
2030 else if (bTabMarked)
2031 xAccessible = GetAccessibleSpreadsheet();
2032 }
2033
2034 DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed");
2035
2036 return xAccessible;
2037 }
2038
2039 void SAL_CALL
deselectAccessibleChild(sal_Int32 nChildIndex)2040 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
2041 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2042 {
2043 ScUnoGuard aGuard;
2044 IsObjectValid();
2045
2046 if (mpChildrenShapes)
2047 {
2048 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
2049 if (mxTempAcc.is())
2050 ++nCount;
2051 if (nChildIndex < 0 || nChildIndex >= nCount)
2052 throw lang::IndexOutOfBoundsException();
2053
2054 sal_Bool bTabMarked(IsTableSelected());
2055
2056 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
2057 if (xAccessible.is())
2058 {
2059 if (mpChildrenShapes)
2060 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
2061
2062 if (bTabMarked)
2063 mpViewShell->SelectAll(); // select the table again
2064 }
2065 else if (bTabMarked)
2066 mpViewShell->Unmark();
2067 }
2068 }
2069
2070 //===== XServiceInfo ====================================================
2071
2072 ::rtl::OUString SAL_CALL
getImplementationName(void)2073 ScAccessibleDocument::getImplementationName(void)
2074 throw (uno::RuntimeException)
2075 {
2076 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
2077 }
2078
2079 uno::Sequence< ::rtl::OUString> SAL_CALL
getSupportedServiceNames(void)2080 ScAccessibleDocument::getSupportedServiceNames(void)
2081 throw (uno::RuntimeException)
2082 {
2083 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
2084 sal_Int32 nOldSize(aSequence.getLength());
2085 aSequence.realloc(nOldSize + 1);
2086 ::rtl::OUString* pNames = aSequence.getArray();
2087
2088 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView"));
2089
2090 return aSequence;
2091 }
2092
2093 //===== XTypeProvider =======================================================
2094
getTypes()2095 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
2096 throw (uno::RuntimeException)
2097 {
2098 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
2099 }
2100
2101 uno::Sequence<sal_Int8> SAL_CALL
getImplementationId(void)2102 ScAccessibleDocument::getImplementationId(void)
2103 throw (uno::RuntimeException)
2104 {
2105 ScUnoGuard aGuard;
2106 IsObjectValid();
2107 static uno::Sequence<sal_Int8> aId;
2108 if (aId.getLength() == 0)
2109 {
2110 aId.realloc (16);
2111 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
2112 }
2113 return aId;
2114 }
2115
2116 ///===== IAccessibleViewForwarder ========================================
2117
IsValid(void) const2118 sal_Bool ScAccessibleDocument::IsValid (void) const
2119 {
2120 ScUnoGuard aGuard;
2121 IsObjectValid();
2122 return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
2123 }
2124
GetVisibleArea_Impl() const2125 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
2126 {
2127 Rectangle aVisRect(GetBoundingBox());
2128
2129 Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point
2130 aPoint.setX(-aPoint.getX());
2131 aPoint.setY(-aPoint.getY());
2132 aVisRect.SetPos(aPoint);
2133
2134 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2135 if (pWin)
2136 aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
2137
2138 return aVisRect;
2139 }
2140
GetVisibleArea() const2141 Rectangle ScAccessibleDocument::GetVisibleArea() const
2142 {
2143 ScUnoGuard aGuard;
2144 IsObjectValid();
2145 return maVisArea;
2146 }
2147
LogicToPixel(const Point & rPoint) const2148 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
2149 {
2150 ScUnoGuard aGuard;
2151 IsObjectValid();
2152 Point aPoint;
2153 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2154 if (pWin)
2155 {
2156 aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
2157 aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
2158 }
2159 return aPoint;
2160 }
2161
LogicToPixel(const Size & rSize) const2162 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
2163 {
2164 ScUnoGuard aGuard;
2165 IsObjectValid();
2166 Size aSize;
2167 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2168 if (pWin)
2169 aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
2170 return aSize;
2171 }
2172
PixelToLogic(const Point & rPoint) const2173 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
2174 {
2175 ScUnoGuard aGuard;
2176 IsObjectValid();
2177 Point aPoint;
2178 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2179 if (pWin)
2180 {
2181 aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
2182 aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
2183 }
2184 return aPoint;
2185 }
2186
PixelToLogic(const Size & rSize) const2187 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
2188 {
2189 ScUnoGuard aGuard;
2190 IsObjectValid();
2191 Size aSize;
2192 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2193 if (pWin)
2194 aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
2195 return aSize;
2196 }
2197
2198 //===== internal ========================================================
2199
GetRelationSet(const ScAddress * pAddress) const2200 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
2201 {
2202 utl::AccessibleRelationSetHelper* pRelationSet = NULL;
2203 if (mpChildrenShapes)
2204 pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
2205 return pRelationSet;
2206 }
2207
2208 ::rtl::OUString SAL_CALL
createAccessibleDescription(void)2209 ScAccessibleDocument::createAccessibleDescription(void)
2210 throw (uno::RuntimeException)
2211 {
2212 rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR));
2213 return sDescription;
2214 }
2215
2216 ::rtl::OUString SAL_CALL
createAccessibleName(void)2217 ScAccessibleDocument::createAccessibleName(void)
2218 throw (uno::RuntimeException)
2219 {
2220 ScUnoGuard aGuard;
2221 IsObjectValid();
2222 rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME));
2223 sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
2224 sName += rtl::OUString::valueOf(nNumber);
2225 return sName;
2226 }
2227
GetBoundingBoxOnScreen() const2228 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
2229 throw (uno::RuntimeException)
2230 {
2231 Rectangle aRect;
2232 if (mpViewShell)
2233 {
2234 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2235 if (pWindow)
2236 aRect = pWindow->GetWindowExtentsRelative(NULL);
2237 }
2238 return aRect;
2239 }
2240
GetBoundingBox() const2241 Rectangle ScAccessibleDocument::GetBoundingBox() const
2242 throw (uno::RuntimeException)
2243 {
2244 Rectangle aRect;
2245 if (mpViewShell)
2246 {
2247 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2248 if (pWindow)
2249 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
2250 }
2251 return aRect;
2252 }
2253
getVisibleTable() const2254 SCTAB ScAccessibleDocument::getVisibleTable() const
2255 {
2256 SCTAB nVisibleTable(0);
2257 if (mpViewShell && mpViewShell->GetViewData())
2258 nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
2259 return nVisibleTable;
2260 }
2261
2262 uno::Reference < XAccessible >
GetAccessibleSpreadsheet()2263 ScAccessibleDocument::GetAccessibleSpreadsheet()
2264 {
2265 if (!mpAccessibleSpreadsheet && mpViewShell)
2266 {
2267 mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
2268 mpAccessibleSpreadsheet->acquire();
2269 mpAccessibleSpreadsheet->Init();
2270 mbCompleteSheetSelected = IsTableSelected();
2271 }
2272 return mpAccessibleSpreadsheet;
2273 }
2274
FreeAccessibleSpreadsheet()2275 void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2276 {
2277 if (mpAccessibleSpreadsheet)
2278 {
2279 mpAccessibleSpreadsheet->dispose();
2280 mpAccessibleSpreadsheet->release();
2281 mpAccessibleSpreadsheet = NULL;
2282 }
2283 }
2284
IsTableSelected() const2285 sal_Bool ScAccessibleDocument::IsTableSelected() const
2286 {
2287 sal_Bool bResult (sal_False);
2288 if(mpViewShell)
2289 {
2290 SCTAB nTab(getVisibleTable());
2291 //#103800#; use a copy of MarkData
2292 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
2293 aMarkData.MarkToMulti();
2294 if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
2295 bResult = sal_True;
2296 }
2297 return bResult;
2298 }
2299
IsDefunc(const uno::Reference<XAccessibleStateSet> & rxParentStates)2300 sal_Bool ScAccessibleDocument::IsDefunc(
2301 const uno::Reference<XAccessibleStateSet>& rxParentStates)
2302 {
2303 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
2304 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
2305 }
2306
IsEditable(const uno::Reference<XAccessibleStateSet> &)2307 sal_Bool ScAccessibleDocument::IsEditable(
2308 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
2309 {
2310 // what is with document protection or readonly documents?
2311 return sal_True;
2312 }
2313
AddChild(const uno::Reference<XAccessible> & xAcc,sal_Bool bFireEvent)2314 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2315 {
2316 DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before");
2317 if (xAcc.is())
2318 {
2319 mxTempAcc = xAcc;
2320 if( bFireEvent )
2321 {
2322 AccessibleEventObject aEvent;
2323 aEvent.Source = uno::Reference<XAccessibleContext>(this);
2324 aEvent.EventId = AccessibleEventId::CHILD;
2325 aEvent.NewValue <<= mxTempAcc;
2326 CommitChange( aEvent );
2327 }
2328 }
2329 }
2330
RemoveChild(const uno::Reference<XAccessible> & xAcc,sal_Bool bFireEvent)2331 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2332 {
2333 DBG_ASSERT(mxTempAcc.is(), "this object should be added before");
2334 if (xAcc.is())
2335 {
2336 DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
2337 if( bFireEvent )
2338 {
2339 AccessibleEventObject aEvent;
2340 aEvent.Source = uno::Reference<XAccessibleContext>(this);
2341 aEvent.EventId = AccessibleEventId::CHILD;
2342 aEvent.OldValue <<= mxTempAcc;
2343 CommitChange( aEvent );
2344 }
2345 mxTempAcc = NULL;
2346 }
2347 }
2348
GetCurrentCellName() const2349 rtl::OUString ScAccessibleDocument::GetCurrentCellName() const
2350 {
2351 String sName( ScResId(STR_ACC_CELL_NAME) );
2352 if (mpViewShell)
2353 {
2354 String sAddress;
2355 // Document not needed, because only the cell address, but not the tablename is needed
2356 mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL );
2357 sName.SearchAndReplaceAscii("%1", sAddress);
2358 }
2359 return rtl::OUString(sName);
2360 }
2361
GetCurrentCellDescription() const2362 rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const
2363 {
2364 return rtl::OUString();
2365 }
GetDocument() const2366 ScDocument *ScAccessibleDocument::GetDocument() const
2367 {
2368 return mpViewShell ? mpViewShell->GetViewData()->GetDocument() : NULL;
2369 }
GetCurCellAddress() const2370 ScAddress ScAccessibleDocument::GetCurCellAddress() const
2371 {
2372 return mpViewShell ? mpViewShell->GetViewData()->GetCurPos() :ScAddress();
2373 }
getExtendedAttributes()2374 uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes()
2375 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
2376 {
2377
2378 uno::Any anyAtrribute;
2379
2380 rtl::OUString sName;
2381 rtl::OUString sValue;
2382 sal_uInt16 sheetIndex;
2383 String sSheetName;
2384 sheetIndex = getVisibleTable();
2385 if(GetDocument()==NULL)
2386 return anyAtrribute;
2387 GetDocument()->GetName(sheetIndex,sSheetName);
2388 sName = rtl::OUString::createFromAscii("page-name:");
2389 sValue = sName + sSheetName ;
2390 sName = rtl::OUString::createFromAscii(";page-number:");
2391 sValue += sName;
2392 sValue += String::CreateFromInt32(sheetIndex+1) ;
2393 sName = rtl::OUString::createFromAscii(";total-pages:");
2394 sValue += sName;
2395 sValue += String::CreateFromInt32(GetDocument()->GetTableCount());
2396 sValue += rtl::OUString::createFromAscii(";");
2397 anyAtrribute <<= sValue;
2398 return anyAtrribute;
2399 }
GetScAccFlowToSequence()2400 com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence()
2401 {
2402 if ( getAccessibleChildCount() )
2403 {
2404 uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table
2405 if ( xSCTableAcc.is() )
2406 {
2407 uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY );
2408 sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount();
2409 if( nSelCount )
2410 {
2411 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell
2412 if ( xSel.is() )
2413 {
2414 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2415 if ( xSelContext.is() )
2416 {
2417 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL )
2418 {
2419 sal_Int32 nParaCount = 0;
2420 uno::Sequence <uno::Any> aSequence(nSelCount);
2421 for ( sal_Int32 i = 0; i < nSelCount; i++ )
2422 {
2423 xSel = xAccSelection->getSelectedAccessibleChild( i ) ;
2424 if ( xSel.is() )
2425 {
2426 xSelContext = xSel->getAccessibleContext();
2427 if ( xSelContext.is() )
2428 {
2429 if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL )
2430 {
2431 aSequence[nParaCount] = uno::makeAny( xSel );
2432 nParaCount++;
2433 }
2434 }
2435 }
2436 }
2437 return aSequence;
2438 }
2439 }
2440 }
2441 }
2442 }
2443 }
2444 uno::Sequence <uno::Any> aEmpty;
2445 return aEmpty;
2446 }
2447 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
get_AccFlowTo(const::com::sun::star::uno::Any & rAny,sal_Int32 nType)2448 SAL_CALL ScAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
2449 throw ( ::com::sun::star::uno::RuntimeException )
2450 {
2451 const sal_Int32 SPELLCHECKFLOWTO = 1;
2452 const sal_Int32 FINDREPLACEFLOWTO = 2;
2453 if ( nType == SPELLCHECKFLOWTO )
2454 {
2455 uno::Reference< ::com::sun::star::drawing::XShape > xShape;
2456 rAny >>= xShape;
2457 if ( xShape.is() )
2458 {
2459 uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape);
2460 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
2461 if ( xAccSelection.is() )
2462 {
2463 if ( xAccSelection->getSelectedAccessibleChildCount() )
2464 {
2465 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
2466 if ( xSel.is() )
2467 {
2468 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2469 if ( xSelContext.is() )
2470 {
2471 //if in sw we find the selected paragraph here
2472 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
2473 {
2474 uno::Sequence<uno::Any> aRet( 1 );
2475 aRet[0] = uno::makeAny( xSel );
2476 return aRet;
2477 }
2478 }
2479 }
2480 }
2481 }
2482 }
2483 else
2484 {
2485 if ( getSelectedAccessibleChildCount() )
2486 {
2487 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 );
2488 if ( xSel.is() )
2489 {
2490 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2491 if ( xSelContext.is() )
2492 {
2493 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY );
2494 if ( xAccChildSelection.is() )
2495 {
2496 if ( xAccChildSelection->getSelectedAccessibleChildCount() )
2497 {
2498 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 );
2499 if ( xChildSel.is() )
2500 {
2501 uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() );
2502 if ( xChildSelContext.is() &&
2503 xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH )
2504 {
2505 uno::Sequence<uno::Any> aRet( 1 );
2506 aRet[0] = uno::makeAny( xChildSel );
2507 return aRet;
2508 }
2509 }
2510 }
2511 }
2512 }
2513 }
2514 }
2515 }
2516 }
2517 else if ( nType == FINDREPLACEFLOWTO )
2518 {
2519 sal_Bool bSuccess(sal_False);
2520 rAny >>= bSuccess;
2521 if ( bSuccess )
2522 {
2523 uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence();
2524 if ( aSeq.getLength() )
2525 {
2526 return aSeq;
2527 }
2528 else if( mpAccessibleSpreadsheet )
2529 {
2530 uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell();
2531 // add xFindCellAcc to the return the Sequence
2532 uno::Sequence< uno::Any> aSeq2(1);
2533 aSeq2[0] = uno::makeAny( xFindCellAcc );
2534 return aSeq2;
2535 }
2536 }
2537 }
2538 uno::Sequence< uno::Any> aEmpty;
2539 return aEmpty;
2540 }
SwitchViewFireFocus()2541 void ScAccessibleDocument::SwitchViewFireFocus()
2542 {
2543 if (mpAccessibleSpreadsheet)
2544 {
2545 mpAccessibleSpreadsheet->FireFirstCellFocus();
2546 }
2547 }
2548
getForeground()2549 sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( )
2550 throw (uno::RuntimeException)
2551 {
2552 return COL_BLACK;
2553 }
2554
getBackground()2555 sal_Int32 SAL_CALL ScAccessibleDocument::getBackground( )
2556 throw (uno::RuntimeException)
2557 {
2558 ScUnoGuard aGuard;
2559 IsObjectValid();
2560 return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
2561 }
2562
2563