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 90 : struct ScShapeDataLess
128 : {
129 : OUString msLayerId;
130 : OUString msZOrder;
131 10 : ScShapeDataLess()
132 : : msLayerId( "LayerID" ),
133 10 : msZOrder( "ZOrder" )
134 : {
135 10 : }
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 : 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 4 : void operator() (ScAccessibleShapeData* pData)
246 : {
247 4 : if (pData)
248 0 : DELETEZ(pData);
249 4 : }
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 : sal_Int8 Compare(const ScAccessibleShapeData* pData1,
334 : const ScAccessibleShapeData* pData2) const;
335 : };
336 :
337 4 : ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
338 : :
339 : mnShapesSelected(0),
340 : mpViewShell(pViewShell),
341 : mpAccessibleDocument(pAccessibleDocument),
342 4 : meSplitPos(eSplitPos)
343 : {
344 4 : FillSelectionSupplier();
345 4 : maZOrderedShapes.push_back(NULL); // add an element which represents the table
346 :
347 4 : GetCount(); // fill list with filtered shapes (no internal shapes)
348 :
349 4 : 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 4 : if (pViewShell)
360 : {
361 4 : ScViewData& rViewData = pViewShell->GetViewData();
362 4 : SfxBroadcaster* pDrawBC = rViewData.GetDocument()->GetDrawBroadcaster();
363 4 : if (pDrawBC)
364 : {
365 4 : StartListening(*pDrawBC);
366 :
367 4 : maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(rViewData.GetDocument()->GetDrawLayer()) );
368 4 : maShapeTreeInfo.SetSdrView(rViewData.GetScDrawView());
369 4 : maShapeTreeInfo.SetController(NULL);
370 4 : maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos));
371 4 : maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
372 : }
373 : }
374 4 : }
375 :
376 12 : ScChildrenShapes::~ScChildrenShapes()
377 : {
378 4 : std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy());
379 4 : if (mpViewShell)
380 : {
381 4 : SfxBroadcaster* pDrawBC = mpViewShell->GetViewData().GetDocument()->GetDrawBroadcaster();
382 4 : if (pDrawBC)
383 4 : EndListening(*pDrawBC);
384 : }
385 8 : }
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 4 : void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint)
407 : {
408 4 : const SdrHint* pSdrHint = dynamic_cast<const SdrHint*>(&rHint);
409 4 : 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 4 : }
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 24 : sal_Int32 ScChildrenShapes::GetCount() const
538 : {
539 24 : SdrPage* pDrawPage = GetDrawPage();
540 24 : 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 24 : return maZOrderedShapes.size();
555 : }
556 :
557 4 : uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
558 : {
559 4 : if (!pData)
560 4 : 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 4 : uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const
583 : {
584 4 : if (maZOrderedShapes.size() <= 1)
585 4 : GetCount(); // fill list with filtered shapes (no internal shapes)
586 :
587 4 : if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size())
588 0 : return NULL;
589 :
590 4 : 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 10 : bool ScChildrenShapes::SelectionChanged()
682 : {
683 10 : bool bResult(false);
684 10 : if (!xSelectionSupplier.is())
685 0 : throw uno::RuntimeException();
686 :
687 10 : uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
688 :
689 10 : bResult = FindSelectedShapesChanges(xShapes, true);
690 :
691 10 : 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 24 : SdrPage* ScChildrenShapes::GetDrawPage() const
885 : {
886 24 : SCTAB nTab(mpAccessibleDocument->getVisibleTable());
887 24 : SdrPage* pDrawPage = NULL;
888 24 : if (mpViewShell)
889 : {
890 24 : ScViewData& rViewData = mpViewShell->GetViewData();
891 24 : ScDocument* pDoc = rViewData.GetDocument();
892 24 : if (pDoc && pDoc->GetDrawLayer())
893 : {
894 24 : ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
895 24 : if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
896 0 : pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
897 : }
898 : }
899 24 : return pDrawPage;
900 : }
901 :
902 : struct SetRelation
903 : {
904 : const ScChildrenShapes* mpChildrenShapes;
905 : mutable utl::AccessibleRelationSetHelper* mpRelationSet;
906 : const ScAddress* mpAddress;
907 2 : SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress)
908 : :
909 : mpChildrenShapes(pChildrenShapes),
910 : mpRelationSet(NULL),
911 2 : mpAddress(pAddress)
912 : {
913 2 : }
914 2 : void operator() (const ScAccessibleShapeData* pAccShapeData) const
915 : {
916 2 : 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 2 : }
931 : };
932 :
933 2 : utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const
934 : {
935 2 : SetRelation aSetRelation(this, pAddress);
936 2 : ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation);
937 2 : return aSetRelation.mpRelationSet;
938 : }
939 :
940 10 : bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, bool /* bCommitChange */) const
941 : {
942 10 : bool bResult(false);
943 10 : SortedShapes aShapesList;
944 20 : uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY);
945 10 : 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 10 : mnShapesSelected = 0;
962 10 : SdrObject *pFocusedObj = NULL;
963 10 : if( mnShapesSelected == 1 && aShapesList.size() == 1)
964 : {
965 0 : pFocusedObj = GetSdrObjectFromXShape(aShapesList[0]->xShape);
966 : }
967 20 : ScShapeDataLess aLess;
968 10 : std::sort(aShapesList.begin(), aShapesList.end(), aLess);
969 20 : SortedShapes vecSelectedShapeAdd;
970 20 : SortedShapes vecSelectedShapeRemove;
971 10 : bool bHasSelect=false;
972 10 : SortedShapes::iterator aXShapesItr(aShapesList.begin());
973 10 : SortedShapes::const_iterator aXShapesEndItr(aShapesList.end());
974 10 : SortedShapes::iterator aDataItr(maZOrderedShapes.begin());
975 10 : SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end());
976 10 : SortedShapes::const_iterator aFocusedItr = aDataEndItr;
977 30 : while((aDataItr != aDataEndItr))
978 : {
979 10 : 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 selction 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->ResetState(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 10 : ++aDataItr;
1031 : }
1032 10 : bool bWinFocus=false;
1033 10 : if (mpViewShell)
1034 : {
1035 10 : ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1036 10 : if (pWin)
1037 : {
1038 10 : bWinFocus = pWin->HasFocus();
1039 : }
1040 : }
1041 10 : const SdrMarkList* pMarkList = NULL;
1042 10 : SdrObject* pMarkedObj = NULL;
1043 10 : SdrObject* pUpObj = NULL;
1044 10 : bool bIsFocuseMarked = true;
1045 10 : 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 10 : if ( bIsFocuseMarked && (aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1) && bWinFocus)
1065 : {
1066 0 : (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED);
1067 : }
1068 10 : 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 10 : 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 10 : SortedShapes::iterator vi = vecSelectedShapeAdd.begin();
1122 10 : 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 10 : SortedShapes::iterator vi = vecSelectedShapeRemove.begin();
1140 10 : 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 10 : std::for_each(aShapesList.begin(), aShapesList.end(), Destroy());
1150 :
1151 20 : return bResult;
1152 : }
1153 :
1154 4 : void ScChildrenShapes::FillSelectionSupplier() const
1155 : {
1156 4 : if (!xSelectionSupplier.is() && mpViewShell)
1157 : {
1158 4 : SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame();
1159 4 : if (pViewFrame)
1160 : {
1161 4 : xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY);
1162 4 : if (xSelectionSupplier.is())
1163 : {
1164 4 : if (mpAccessibleDocument)
1165 4 : xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument);
1166 4 : uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY);
1167 4 : if (xShapes.is())
1168 0 : mnShapesSelected = xShapes->getCount();
1169 : }
1170 : }
1171 : }
1172 4 : }
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 && pRelationSet && 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) const
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 4 : 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 4 : mbCompleteSheetSelected(false)
1413 : {
1414 4 : if (pViewShell)
1415 : {
1416 4 : pViewShell->AddAccessibilityObject(*this);
1417 4 : vcl::Window *pWin = pViewShell->GetWindowByPos(eSplitPos);
1418 4 : if( pWin )
1419 : {
1420 4 : pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1421 4 : sal_uInt16 nCount = pWin->GetChildCount();
1422 4 : 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 4 : ScViewData& rViewData = pViewShell->GetViewData();
1431 4 : 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 4 : maVisArea = GetVisibleArea_Impl();
1440 4 : }
1441 :
1442 4 : void ScAccessibleDocument::Init()
1443 : {
1444 4 : if(!mpChildrenShapes)
1445 4 : mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos);
1446 4 : }
1447 :
1448 12 : ScAccessibleDocument::~ScAccessibleDocument(void)
1449 : {
1450 4 : 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 8 : }
1457 :
1458 4 : void SAL_CALL ScAccessibleDocument::disposing()
1459 : {
1460 4 : SolarMutexGuard aGuard;
1461 4 : FreeAccessibleSpreadsheet();
1462 4 : if (mpViewShell)
1463 : {
1464 4 : vcl::Window *pWin = mpViewShell->GetWindowByPos(meSplitPos);
1465 4 : if( pWin )
1466 4 : pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1467 :
1468 4 : mpViewShell->RemoveAccessibilityObject(*this);
1469 4 : mpViewShell = NULL;
1470 : }
1471 4 : if (mpChildrenShapes)
1472 4 : DELETEZ(mpChildrenShapes);
1473 :
1474 4 : ScAccessibleDocumentBase::disposing();
1475 4 : }
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 24 : IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
1486 : {
1487 : OSL_ENSURE( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
1488 12 : if ( pEvent && pEvent->ISA( VclWindowEvent ) )
1489 : {
1490 12 : VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
1491 : OSL_ENSURE( pVclEvent->GetWindow(), "Window???" );
1492 12 : 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 12 : return 0;
1515 : }
1516 :
1517 32 : void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1518 : {
1519 32 : if (dynamic_cast<const ScAccGridWinFocusLostHint*>(&rHint) )
1520 : {
1521 4 : const ScAccGridWinFocusLostHint* pFocusLostHint = static_cast<const ScAccGridWinFocusLostHint *>(&rHint);
1522 4 : if (pFocusLostHint->GetOldGridWin() == meSplitPos)
1523 : {
1524 4 : if (mxTempAcc.is() && mpTempAccEdit)
1525 0 : mpTempAccEdit->LostFocus();
1526 4 : else if (mpAccessibleSpreadsheet)
1527 4 : mpAccessibleSpreadsheet->LostFocus();
1528 : else
1529 0 : CommitFocusLost();
1530 4 : }
1531 : }
1532 28 : 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 28 : else if (dynamic_cast<const SfxSimpleHint*>(&rHint))
1564 : {
1565 28 : const SfxSimpleHint* pSimpleHint = static_cast<const SfxSimpleHint*>(&rHint);
1566 : // only notify if child exist, otherwise it is not necessary
1567 28 : 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 28 : else if (pSimpleHint->GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
1592 : {
1593 0 : if (mpChildrenShapes)
1594 0 : mpChildrenShapes->SetDrawBroadcaster();
1595 : }
1596 28 : 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 28 : 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 28 : else if ((pSimpleHint->GetId() == SC_HINT_ACC_VISAREACHANGED) || (pSimpleHint->GetId() == SC_HINT_ACC_WINDOWRESIZED))
1636 : {
1637 4 : Rectangle aOldVisArea(maVisArea);
1638 4 : maVisArea = GetVisibleArea_Impl();
1639 :
1640 4 : 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 32 : ScAccessibleDocumentBase::Notify(rBC, rHint);
1666 32 : }
1667 :
1668 10 : void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
1669 : throw (uno::RuntimeException, std::exception)
1670 : {
1671 10 : bool bSelectionChanged(false);
1672 10 : if (mpAccessibleSpreadsheet)
1673 : {
1674 10 : bool bOldSelected(mbCompleteSheetSelected);
1675 10 : mbCompleteSheetSelected = IsTableSelected();
1676 10 : if (bOldSelected != mbCompleteSheetSelected)
1677 : {
1678 0 : mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
1679 0 : bSelectionChanged = true;
1680 : }
1681 : }
1682 :
1683 10 : if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
1684 0 : bSelectionChanged = true;
1685 :
1686 10 : 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 10 : }
1695 :
1696 : //===== XInterface =====================================================
1697 :
1698 46 : uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
1699 : throw (uno::RuntimeException, std::exception)
1700 : {
1701 46 : uno::Any aAnyTmp;
1702 46 : 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 92 : uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
1709 92 : return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
1710 : }
1711 :
1712 354 : void SAL_CALL ScAccessibleDocument::acquire()
1713 : throw ()
1714 : {
1715 354 : ScAccessibleContextBase::acquire();
1716 354 : }
1717 :
1718 354 : void SAL_CALL ScAccessibleDocument::release()
1719 : throw ()
1720 : {
1721 354 : ScAccessibleContextBase::release();
1722 354 : }
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 2 : void SAL_CALL ScAccessibleDocument::grabFocus( )
1758 : throw (uno::RuntimeException, std::exception)
1759 : {
1760 2 : SolarMutexGuard aGuard;
1761 2 : IsObjectValid();
1762 2 : if (getAccessibleParent().is())
1763 : {
1764 2 : uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1765 2 : if (xAccessibleComponent.is())
1766 : {
1767 2 : xAccessibleComponent->grabFocus();
1768 : // grab only focus if it does not have the focus and it is not hidden
1769 4 : if (mpViewShell &&
1770 2 : (mpViewShell->GetViewData().GetActivePart() != meSplitPos) &&
1771 0 : mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
1772 : {
1773 0 : mpViewShell->ActivatePart(meSplitPos);
1774 : }
1775 2 : }
1776 2 : }
1777 2 : }
1778 :
1779 : //===== XAccessibleContext ==============================================
1780 :
1781 : /// Return the number of currently visible children.
1782 : sal_Int32 SAL_CALL
1783 12 : ScAccessibleDocument::getAccessibleChildCount(void)
1784 : throw (uno::RuntimeException, std::exception)
1785 : {
1786 12 : SolarMutexGuard aGuard;
1787 12 : IsObjectValid();
1788 12 : sal_Int32 nCount(1);
1789 12 : if (mpChildrenShapes)
1790 12 : nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
1791 :
1792 12 : if (mxTempAcc.is())
1793 0 : ++nCount;
1794 :
1795 12 : return nCount;
1796 : }
1797 :
1798 : /// Return the specified child or NULL if index is invalid.
1799 : uno::Reference<XAccessible> SAL_CALL
1800 4 : ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex)
1801 : throw (uno::RuntimeException,
1802 : lang::IndexOutOfBoundsException, std::exception)
1803 : {
1804 4 : SolarMutexGuard aGuard;
1805 4 : IsObjectValid();
1806 4 : uno::Reference<XAccessible> xAccessible;
1807 4 : if (nIndex >= 0)
1808 : {
1809 4 : sal_Int32 nCount(1);
1810 4 : if (mpChildrenShapes)
1811 : {
1812 4 : xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
1813 4 : nCount = mpChildrenShapes->GetCount(); //there is always a table
1814 : }
1815 4 : if (!xAccessible.is())
1816 : {
1817 4 : if (nIndex < nCount)
1818 4 : xAccessible = GetAccessibleSpreadsheet();
1819 0 : else if (nIndex == nCount && mxTempAcc.is())
1820 0 : xAccessible = mxTempAcc;
1821 : }
1822 : }
1823 :
1824 4 : if (!xAccessible.is())
1825 0 : throw lang::IndexOutOfBoundsException();
1826 :
1827 4 : return xAccessible;
1828 : }
1829 :
1830 : /// Return the set of current states.
1831 : uno::Reference<XAccessibleStateSet> SAL_CALL
1832 28 : ScAccessibleDocument::getAccessibleStateSet(void)
1833 : throw (uno::RuntimeException, std::exception)
1834 : {
1835 28 : SolarMutexGuard aGuard;
1836 56 : uno::Reference<XAccessibleStateSet> xParentStates;
1837 28 : if (getAccessibleParent().is())
1838 : {
1839 28 : uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1840 28 : xParentStates = xParentContext->getAccessibleStateSet();
1841 : }
1842 28 : utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1843 28 : if (IsDefunc(xParentStates))
1844 0 : pStateSet->AddState(AccessibleStateType::DEFUNC);
1845 : else
1846 : {
1847 28 : if (IsEditable(xParentStates))
1848 28 : pStateSet->AddState(AccessibleStateType::EDITABLE);
1849 28 : pStateSet->AddState(AccessibleStateType::ENABLED);
1850 28 : pStateSet->AddState(AccessibleStateType::OPAQUE);
1851 28 : if (isShowing())
1852 28 : pStateSet->AddState(AccessibleStateType::SHOWING);
1853 28 : if (isVisible())
1854 28 : pStateSet->AddState(AccessibleStateType::VISIBLE);
1855 : }
1856 56 : return pStateSet;
1857 : }
1858 :
1859 : OUString SAL_CALL
1860 4 : ScAccessibleDocument::getAccessibleName(void)
1861 : throw (::com::sun::star::uno::RuntimeException, std::exception)
1862 : {
1863 4 : SolarMutexGuard g;
1864 :
1865 4 : OUString aName = ScResId(STR_ACC_DOC_SPREADSHEET);
1866 4 : ScDocument* pScDoc = GetDocument();
1867 4 : if (!pScDoc)
1868 0 : return aName;
1869 :
1870 4 : SfxObjectShell* pObjSh = pScDoc->GetDocumentShell();
1871 4 : if (!pObjSh)
1872 0 : return aName;
1873 :
1874 8 : OUString aFileName;
1875 4 : SfxMedium* pMed = pObjSh->GetMedium();
1876 4 : if (pMed)
1877 4 : aFileName = pMed->GetName();
1878 :
1879 4 : if (aFileName.isEmpty())
1880 4 : aFileName = pObjSh->GetTitle(SFX_TITLE_APINAME);
1881 :
1882 4 : if (!aFileName.isEmpty())
1883 : {
1884 4 : OUString aReadOnly;
1885 4 : if (pObjSh->IsReadOnly())
1886 0 : aReadOnly = ScResId(STR_ACC_DOC_SPREADSHEET_READONLY);
1887 :
1888 4 : aName = aFileName + aReadOnly + " - " + aName;
1889 : }
1890 8 : return aName;
1891 : }
1892 :
1893 : ///===== XAccessibleSelection ===========================================
1894 :
1895 : void SAL_CALL
1896 0 : ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
1897 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1898 : {
1899 0 : SolarMutexGuard aGuard;
1900 0 : IsObjectValid();
1901 :
1902 0 : if (mpChildrenShapes && mpViewShell)
1903 : {
1904 0 : sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1905 0 : if (mxTempAcc.is())
1906 0 : ++nCount;
1907 0 : if (nChildIndex < 0 || nChildIndex >= nCount)
1908 0 : throw lang::IndexOutOfBoundsException();
1909 :
1910 0 : uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1911 0 : if (xAccessible.is())
1912 : {
1913 0 : bool bWasTableSelected(IsTableSelected());
1914 :
1915 0 : if (mpChildrenShapes)
1916 0 : mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1917 :
1918 0 : if (bWasTableSelected)
1919 0 : mpViewShell->SelectAll();
1920 : }
1921 : else
1922 : {
1923 0 : if (mpViewShell)
1924 0 : mpViewShell->SelectAll();
1925 0 : }
1926 0 : }
1927 0 : }
1928 :
1929 : sal_Bool SAL_CALL
1930 0 : ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
1931 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1932 : {
1933 0 : SolarMutexGuard aGuard;
1934 0 : IsObjectValid();
1935 0 : bool bResult(false);
1936 :
1937 0 : if (mpChildrenShapes)
1938 : {
1939 0 : sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1940 0 : if (mxTempAcc.is())
1941 0 : ++nCount;
1942 0 : if (nChildIndex < 0 || nChildIndex >= nCount)
1943 0 : throw lang::IndexOutOfBoundsException();
1944 :
1945 0 : uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1946 0 : if (xAccessible.is())
1947 : {
1948 0 : uno::Reference<drawing::XShape> xShape;
1949 0 : bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high
1950 : }
1951 : else
1952 : {
1953 0 : if (mxTempAcc.is() && nChildIndex == nCount)
1954 0 : bResult = true;
1955 : else
1956 0 : bResult = IsTableSelected();
1957 0 : }
1958 : }
1959 0 : return bResult;
1960 : }
1961 :
1962 : void SAL_CALL
1963 0 : ScAccessibleDocument::clearAccessibleSelection( )
1964 : throw (uno::RuntimeException, std::exception)
1965 : {
1966 0 : SolarMutexGuard aGuard;
1967 0 : IsObjectValid();
1968 :
1969 0 : if (mpChildrenShapes)
1970 0 : mpChildrenShapes->DeselectAll(); //deselects all (also the table)
1971 0 : }
1972 :
1973 : void SAL_CALL
1974 0 : ScAccessibleDocument::selectAllAccessibleChildren( )
1975 : throw (uno::RuntimeException, std::exception)
1976 : {
1977 0 : SolarMutexGuard aGuard;
1978 0 : IsObjectValid();
1979 :
1980 0 : if (mpChildrenShapes)
1981 0 : mpChildrenShapes->SelectAll();
1982 :
1983 : // select table after shapes, because while selecting shapes the table will be deselected
1984 0 : if (mpViewShell)
1985 : {
1986 0 : mpViewShell->SelectAll();
1987 0 : }
1988 0 : }
1989 :
1990 : sal_Int32 SAL_CALL
1991 0 : ScAccessibleDocument::getSelectedAccessibleChildCount( )
1992 : throw (uno::RuntimeException, std::exception)
1993 : {
1994 0 : SolarMutexGuard aGuard;
1995 0 : IsObjectValid();
1996 0 : sal_Int32 nCount(0);
1997 :
1998 0 : if (mpChildrenShapes)
1999 0 : nCount = mpChildrenShapes->GetSelectedCount();
2000 :
2001 0 : if (IsTableSelected())
2002 0 : ++nCount;
2003 :
2004 0 : if (mxTempAcc.is())
2005 0 : ++nCount;
2006 :
2007 0 : return nCount;
2008 : }
2009 :
2010 : uno::Reference<XAccessible > SAL_CALL
2011 0 : ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
2012 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2013 : {
2014 0 : SolarMutexGuard aGuard;
2015 0 : IsObjectValid();
2016 0 : uno::Reference<XAccessible> xAccessible;
2017 0 : if (mpChildrenShapes)
2018 : {
2019 0 : sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
2020 0 : if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
2021 0 : throw lang::IndexOutOfBoundsException();
2022 :
2023 0 : bool bTabMarked(IsTableSelected());
2024 :
2025 0 : if (mpChildrenShapes)
2026 0 : xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
2027 0 : if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
2028 0 : xAccessible = mxTempAcc;
2029 0 : else if (bTabMarked)
2030 0 : xAccessible = GetAccessibleSpreadsheet();
2031 : }
2032 :
2033 : OSL_ENSURE(xAccessible.is(), "here should always be an accessible object or a exception throwed");
2034 :
2035 0 : return xAccessible;
2036 : }
2037 :
2038 : void SAL_CALL
2039 0 : ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
2040 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2041 : {
2042 0 : SolarMutexGuard aGuard;
2043 0 : IsObjectValid();
2044 :
2045 0 : if (mpChildrenShapes && mpViewShell)
2046 : {
2047 0 : sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
2048 0 : if (mxTempAcc.is())
2049 0 : ++nCount;
2050 0 : if (nChildIndex < 0 || nChildIndex >= nCount)
2051 0 : throw lang::IndexOutOfBoundsException();
2052 :
2053 0 : bool bTabMarked(IsTableSelected());
2054 :
2055 0 : uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
2056 0 : if (xAccessible.is())
2057 : {
2058 0 : if (mpChildrenShapes)
2059 0 : mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
2060 :
2061 0 : if (bTabMarked)
2062 0 : mpViewShell->SelectAll(); // select the table again
2063 : }
2064 0 : else if (bTabMarked)
2065 0 : mpViewShell->Unmark();
2066 0 : }
2067 0 : }
2068 :
2069 : //===== XServiceInfo ====================================================
2070 :
2071 : OUString SAL_CALL
2072 0 : ScAccessibleDocument::getImplementationName(void)
2073 : throw (uno::RuntimeException, std::exception)
2074 : {
2075 0 : return OUString("ScAccessibleDocument");
2076 : }
2077 :
2078 : uno::Sequence< OUString> SAL_CALL
2079 0 : ScAccessibleDocument::getSupportedServiceNames(void)
2080 : throw (uno::RuntimeException, std::exception)
2081 : {
2082 0 : uno::Sequence< OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
2083 0 : sal_Int32 nOldSize(aSequence.getLength());
2084 0 : aSequence.realloc(nOldSize + 1);
2085 :
2086 0 : aSequence[nOldSize] = "com.sun.star.AccessibleSpreadsheetDocumentView";
2087 :
2088 0 : return aSequence;
2089 : }
2090 :
2091 : //===== XTypeProvider =======================================================
2092 :
2093 0 : uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
2094 : throw (uno::RuntimeException, std::exception)
2095 : {
2096 0 : return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
2097 : }
2098 :
2099 : uno::Sequence<sal_Int8> SAL_CALL
2100 0 : ScAccessibleDocument::getImplementationId(void)
2101 : throw (uno::RuntimeException, std::exception)
2102 : {
2103 0 : return css::uno::Sequence<sal_Int8>();
2104 : }
2105 :
2106 : ///===== IAccessibleViewForwarder ========================================
2107 :
2108 0 : bool ScAccessibleDocument::IsValid (void) const
2109 : {
2110 0 : SolarMutexGuard aGuard;
2111 0 : IsObjectValid();
2112 0 : return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
2113 : }
2114 :
2115 8 : Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
2116 : {
2117 8 : Rectangle aVisRect(GetBoundingBox());
2118 :
2119 8 : if (mpViewShell)
2120 : {
2121 8 : Point aPoint(mpViewShell->GetViewData().GetPixPos(meSplitPos)); // returns a negative Point
2122 8 : aPoint.setX(-aPoint.getX());
2123 8 : aPoint.setY(-aPoint.getY());
2124 8 : aVisRect.SetPos(aPoint);
2125 :
2126 8 : ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2127 8 : if (pWin)
2128 8 : aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
2129 : }
2130 :
2131 8 : return aVisRect;
2132 : }
2133 :
2134 0 : Rectangle ScAccessibleDocument::GetVisibleArea() const
2135 : {
2136 0 : SolarMutexGuard aGuard;
2137 0 : IsObjectValid();
2138 0 : return maVisArea;
2139 : }
2140 :
2141 0 : Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
2142 : {
2143 0 : SolarMutexGuard aGuard;
2144 0 : IsObjectValid();
2145 0 : Point aPoint;
2146 0 : ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2147 0 : if (pWin)
2148 : {
2149 0 : aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
2150 0 : aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
2151 : }
2152 0 : return aPoint;
2153 : }
2154 :
2155 0 : Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
2156 : {
2157 0 : SolarMutexGuard aGuard;
2158 0 : IsObjectValid();
2159 0 : Size aSize;
2160 0 : ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2161 0 : if (pWin)
2162 0 : aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
2163 0 : return aSize;
2164 : }
2165 :
2166 0 : Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
2167 : {
2168 0 : SolarMutexGuard aGuard;
2169 0 : IsObjectValid();
2170 0 : Point aPoint;
2171 0 : ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2172 0 : if (pWin)
2173 : {
2174 0 : aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
2175 0 : aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
2176 : }
2177 0 : return aPoint;
2178 : }
2179 :
2180 0 : Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
2181 : {
2182 0 : SolarMutexGuard aGuard;
2183 0 : IsObjectValid();
2184 0 : Size aSize;
2185 0 : ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
2186 0 : if (pWin)
2187 0 : aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
2188 0 : return aSize;
2189 : }
2190 :
2191 : //===== internal ========================================================
2192 :
2193 2 : utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
2194 : {
2195 2 : utl::AccessibleRelationSetHelper* pRelationSet = NULL;
2196 2 : if (mpChildrenShapes)
2197 2 : pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
2198 2 : return pRelationSet;
2199 : }
2200 :
2201 : OUString SAL_CALL
2202 4 : ScAccessibleDocument::createAccessibleDescription(void)
2203 : throw (uno::RuntimeException)
2204 : {
2205 4 : OUString sDescription = OUString(ScResId(STR_ACC_DOC_DESCR));
2206 4 : return sDescription;
2207 : }
2208 :
2209 : OUString SAL_CALL
2210 0 : ScAccessibleDocument::createAccessibleName(void)
2211 : throw (uno::RuntimeException, std::exception)
2212 : {
2213 0 : SolarMutexGuard aGuard;
2214 0 : IsObjectValid();
2215 0 : OUString sName = OUString(ScResId(STR_ACC_DOC_NAME));
2216 0 : sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
2217 0 : sName += OUString::number(nNumber);
2218 0 : return sName;
2219 : }
2220 :
2221 0 : Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
2222 : throw (uno::RuntimeException, std::exception)
2223 : {
2224 0 : Rectangle aRect;
2225 0 : if (mpViewShell)
2226 : {
2227 0 : vcl::Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2228 0 : if (pWindow)
2229 0 : aRect = pWindow->GetWindowExtentsRelative(NULL);
2230 : }
2231 0 : return aRect;
2232 : }
2233 :
2234 60 : Rectangle ScAccessibleDocument::GetBoundingBox() const
2235 : throw (uno::RuntimeException, std::exception)
2236 : {
2237 60 : Rectangle aRect;
2238 60 : if (mpViewShell)
2239 : {
2240 60 : vcl::Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2241 60 : if (pWindow)
2242 60 : aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
2243 : }
2244 60 : return aRect;
2245 : }
2246 :
2247 42 : SCTAB ScAccessibleDocument::getVisibleTable() const
2248 : {
2249 42 : SCTAB nVisibleTable(0);
2250 42 : if (mpViewShell)
2251 42 : nVisibleTable = mpViewShell->GetViewData().GetTabNo();
2252 42 : return nVisibleTable;
2253 : }
2254 :
2255 : uno::Reference < XAccessible >
2256 4 : ScAccessibleDocument::GetAccessibleSpreadsheet()
2257 : {
2258 4 : if (!mpAccessibleSpreadsheet && mpViewShell)
2259 : {
2260 4 : mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
2261 4 : mpAccessibleSpreadsheet->acquire();
2262 4 : mpAccessibleSpreadsheet->Init();
2263 4 : mbCompleteSheetSelected = IsTableSelected();
2264 : }
2265 4 : return mpAccessibleSpreadsheet;
2266 : }
2267 :
2268 4 : void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2269 : {
2270 4 : if (mpAccessibleSpreadsheet)
2271 : {
2272 4 : mpAccessibleSpreadsheet->dispose();
2273 4 : mpAccessibleSpreadsheet->release();
2274 4 : mpAccessibleSpreadsheet = NULL;
2275 : }
2276 4 : }
2277 :
2278 14 : bool ScAccessibleDocument::IsTableSelected() const
2279 : {
2280 14 : bool bResult (false);
2281 14 : if(mpViewShell)
2282 : {
2283 14 : SCTAB nTab(getVisibleTable());
2284 : //#103800#; use a copy of MarkData
2285 14 : ScMarkData aMarkData(mpViewShell->GetViewData().GetMarkData());
2286 14 : aMarkData.MarkToMulti();
2287 14 : if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
2288 0 : bResult = true;
2289 : }
2290 14 : return bResult;
2291 : }
2292 :
2293 28 : bool ScAccessibleDocument::IsDefunc(
2294 : const uno::Reference<XAccessibleStateSet>& rxParentStates)
2295 : {
2296 112 : return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
2297 112 : (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
2298 : }
2299 :
2300 28 : bool ScAccessibleDocument::IsEditable(
2301 : const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
2302 : {
2303 : // what is with document protection or readonly documents?
2304 28 : return true;
2305 : }
2306 :
2307 0 : void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, bool bFireEvent)
2308 : {
2309 : OSL_ENSURE(!mxTempAcc.is(), "this object should be removed before");
2310 0 : if (xAcc.is())
2311 : {
2312 0 : mxTempAcc = xAcc;
2313 0 : if( bFireEvent )
2314 : {
2315 0 : AccessibleEventObject aEvent;
2316 0 : aEvent.Source = uno::Reference<XAccessibleContext>(this);
2317 0 : aEvent.EventId = AccessibleEventId::CHILD;
2318 0 : aEvent.NewValue <<= mxTempAcc;
2319 0 : CommitChange( aEvent );
2320 : }
2321 : }
2322 0 : }
2323 :
2324 0 : void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, bool bFireEvent)
2325 : {
2326 : OSL_ENSURE(mxTempAcc.is(), "this object should be added before");
2327 0 : if (xAcc.is())
2328 : {
2329 : OSL_ENSURE(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
2330 0 : if( bFireEvent )
2331 : {
2332 0 : AccessibleEventObject aEvent;
2333 0 : aEvent.Source = uno::Reference<XAccessibleContext>(this);
2334 0 : aEvent.EventId = AccessibleEventId::CHILD;
2335 0 : aEvent.OldValue <<= mxTempAcc;
2336 0 : CommitChange( aEvent );
2337 : }
2338 0 : mxTempAcc = NULL;
2339 : }
2340 0 : }
2341 :
2342 0 : OUString ScAccessibleDocument::GetCurrentCellName() const
2343 : {
2344 0 : OUString sName(SC_RESSTR(STR_ACC_CELL_NAME));
2345 0 : if (mpViewShell)
2346 : {
2347 : // Document not needed, because only the cell address, but not the tablename is needed
2348 0 : OUString sAddress(mpViewShell->GetViewData().GetCurPos().Format(SCA_VALID, NULL));
2349 0 : sName = sName.replaceFirst("%1", sAddress);
2350 : }
2351 0 : return sName;
2352 : }
2353 :
2354 0 : OUString ScAccessibleDocument::GetCurrentCellDescription() const
2355 : {
2356 0 : return OUString();
2357 : }
2358 :
2359 4 : ScDocument *ScAccessibleDocument::GetDocument() const
2360 : {
2361 4 : return mpViewShell ? mpViewShell->GetViewData().GetDocument() : NULL;
2362 : }
2363 :
2364 0 : ScAddress ScAccessibleDocument::GetCurCellAddress() const
2365 : {
2366 0 : return mpViewShell ? mpViewShell->GetViewData().GetCurPos() : ScAddress();
2367 : }
2368 :
2369 0 : uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes()
2370 : throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
2371 : {
2372 0 : SolarMutexGuard g;
2373 :
2374 0 : uno::Any anyAtrribute;
2375 :
2376 0 : OUString sName;
2377 0 : OUString sValue;
2378 : sal_uInt16 sheetIndex;
2379 0 : OUString sSheetName;
2380 0 : sheetIndex = getVisibleTable();
2381 0 : if(GetDocument()==NULL)
2382 0 : return anyAtrribute;
2383 0 : GetDocument()->GetName(sheetIndex,sSheetName);
2384 0 : sName = "page-name:";
2385 0 : sValue = sName + sSheetName ;
2386 0 : sName = ";page-number:";
2387 0 : sValue += sName;
2388 0 : sValue += OUString::number(sheetIndex+1) ;
2389 0 : sName = ";total-pages:";
2390 0 : sValue += sName;
2391 0 : sValue += OUString::number(GetDocument()->GetTableCount());
2392 0 : sValue += ";";
2393 0 : anyAtrribute <<= sValue;
2394 0 : return anyAtrribute;
2395 : }
2396 :
2397 0 : com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence()
2398 : {
2399 0 : if ( getAccessibleChildCount() )
2400 : {
2401 0 : uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table
2402 0 : if ( xSCTableAcc.is() )
2403 : {
2404 0 : uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY );
2405 0 : sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount();
2406 0 : if( nSelCount )
2407 : {
2408 0 : uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell
2409 0 : if ( xSel.is() )
2410 : {
2411 0 : uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2412 0 : if ( xSelContext.is() )
2413 : {
2414 0 : if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL )
2415 : {
2416 0 : sal_Int32 nParaCount = 0;
2417 0 : uno::Sequence <uno::Any> aSequence(nSelCount);
2418 0 : for ( sal_Int32 i = 0; i < nSelCount; i++ )
2419 : {
2420 0 : xSel = xAccSelection->getSelectedAccessibleChild( i ) ;
2421 0 : if ( xSel.is() )
2422 : {
2423 0 : xSelContext = xSel->getAccessibleContext();
2424 0 : if ( xSelContext.is() )
2425 : {
2426 0 : if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL )
2427 : {
2428 0 : aSequence[nParaCount] = uno::makeAny( xSel );
2429 0 : nParaCount++;
2430 : }
2431 : }
2432 : }
2433 : }
2434 0 : return aSequence;
2435 : }
2436 0 : }
2437 0 : }
2438 0 : }
2439 0 : }
2440 : }
2441 0 : uno::Sequence <uno::Any> aEmpty;
2442 0 : return aEmpty;
2443 : }
2444 :
2445 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
2446 0 : SAL_CALL ScAccessibleDocument::getAccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
2447 : throw ( ::com::sun::star::uno::RuntimeException, std::exception )
2448 : {
2449 0 : SolarMutexGuard g;
2450 :
2451 0 : const sal_Int32 SPELLCHECKFLOWTO = 1;
2452 0 : const sal_Int32 FINDREPLACEFLOWTO = 2;
2453 0 : if ( nType == SPELLCHECKFLOWTO )
2454 : {
2455 0 : uno::Reference< ::com::sun::star::drawing::XShape > xShape;
2456 0 : rAny >>= xShape;
2457 0 : if ( xShape.is() )
2458 : {
2459 0 : uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape);
2460 0 : uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
2461 0 : if ( xAccSelection.is() )
2462 : {
2463 0 : if ( xAccSelection->getSelectedAccessibleChildCount() )
2464 : {
2465 0 : uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
2466 0 : if ( xSel.is() )
2467 : {
2468 0 : uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2469 0 : if ( xSelContext.is() )
2470 : {
2471 : //if in sw we find the selected paragraph here
2472 0 : if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
2473 : {
2474 0 : uno::Sequence<uno::Any> aRet( 1 );
2475 0 : aRet[0] = uno::makeAny( xSel );
2476 0 : return aRet;
2477 : }
2478 0 : }
2479 0 : }
2480 : }
2481 0 : }
2482 : }
2483 : else
2484 : {
2485 0 : if ( getSelectedAccessibleChildCount() )
2486 : {
2487 0 : uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 );
2488 0 : if ( xSel.is() )
2489 : {
2490 0 : uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
2491 0 : if ( xSelContext.is() )
2492 : {
2493 0 : uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY );
2494 0 : if ( xAccChildSelection.is() )
2495 : {
2496 0 : if ( xAccChildSelection->getSelectedAccessibleChildCount() )
2497 : {
2498 0 : uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 );
2499 0 : if ( xChildSel.is() )
2500 : {
2501 0 : uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() );
2502 0 : if ( xChildSelContext.is() &&
2503 0 : xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH )
2504 : {
2505 0 : uno::Sequence<uno::Any> aRet( 1 );
2506 0 : aRet[0] = uno::makeAny( xChildSel );
2507 0 : return aRet;
2508 0 : }
2509 0 : }
2510 : }
2511 0 : }
2512 0 : }
2513 0 : }
2514 : }
2515 0 : }
2516 : }
2517 0 : else if ( nType == FINDREPLACEFLOWTO )
2518 : {
2519 0 : bool bSuccess(false);
2520 0 : rAny >>= bSuccess;
2521 0 : if ( bSuccess )
2522 : {
2523 0 : uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence();
2524 0 : if ( aSeq.getLength() )
2525 : {
2526 0 : return aSeq;
2527 : }
2528 0 : else if( mpAccessibleSpreadsheet )
2529 : {
2530 0 : uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell();
2531 : // add xFindCellAcc to the return the Sequence
2532 0 : uno::Sequence< uno::Any> aSeq2(1);
2533 0 : aSeq2[0] = uno::makeAny( xFindCellAcc );
2534 0 : return aSeq2;
2535 0 : }
2536 : }
2537 : }
2538 0 : uno::Sequence< uno::Any> aEmpty;
2539 0 : return aEmpty;
2540 : }
2541 :
2542 0 : void ScAccessibleDocument::SwitchViewFireFocus()
2543 : {
2544 0 : if (mpAccessibleSpreadsheet)
2545 : {
2546 0 : mpAccessibleSpreadsheet->FireFirstCellFocus();
2547 : }
2548 0 : }
2549 :
2550 0 : sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( )
2551 : throw (uno::RuntimeException, std::exception)
2552 : {
2553 0 : return COL_BLACK;
2554 : }
2555 :
2556 0 : sal_Int32 SAL_CALL ScAccessibleDocument::getBackground( )
2557 : throw (uno::RuntimeException, std::exception)
2558 : {
2559 0 : SolarMutexGuard aGuard;
2560 0 : IsObjectValid();
2561 0 : return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
2562 228 : }
2563 :
2564 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|