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