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