fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleDocument.cxx
blobd4d126d0b25e0f3cf87f00d2862403d28645484f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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.
24 * The symbols "extents" and "indices" come from boost::multi_array.
27 #ifdef indices
28 #undef indices
29 #endif
30 #define indices dummy1_indices
32 #ifdef extents
33 #undef extents
34 #endif
35 #define extents dummy1_extents
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 "markdata.hxx"
53 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
54 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
55 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
56 #include <com/sun/star/view/XSelectionSupplier.hpp>
57 #include <com/sun/star/drawing/XShape.hpp>
58 #include <com/sun/star/drawing/XShapes.hpp>
60 #include <unotools/accessiblestatesethelper.hxx>
61 #include <tools/gen.hxx>
62 #include <svx/svdpage.hxx>
63 #include <svx/svdobj.hxx>
64 #include <svx/ShapeTypeHandler.hxx>
65 #include <svx/AccessibleShape.hxx>
66 #include <svx/AccessibleShapeTreeInfo.hxx>
67 #include <svx/AccessibleShapeInfo.hxx>
68 #include <comphelper/sequence.hxx>
69 #include <comphelper/servicehelper.hxx>
70 #include <sfx2/viewfrm.hxx>
71 #include <svx/unoshcol.hxx>
72 #include <svx/unoshape.hxx>
73 #include <unotools/accessiblerelationsethelper.hxx>
74 #include <toolkit/helper/convert.hxx>
75 #include <vcl/svapp.hxx>
77 #include <list>
78 #include <algorithm>
80 #ifdef indices
81 #undef indices
82 #endif
84 #ifdef extents
85 #undef extents
86 #endif
88 using namespace ::com::sun::star;
89 using namespace ::com::sun::star::accessibility;
90 using ::std::for_each;
92 //===== internal ========================================================
94 struct ScAccessibleShapeData
96 ScAccessibleShapeData() : pAccShape(NULL), pRelationCell(NULL), bSelected(false), bSelectable(sal_True) {}
97 ~ScAccessibleShapeData();
98 mutable ::accessibility::AccessibleShape* pAccShape;
99 mutable ScAddress* pRelationCell; // if it is NULL this shape is anchored on the table
100 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
101 mutable sal_Bool bSelected;
102 sal_Bool bSelectable;
105 ScAccessibleShapeData::~ScAccessibleShapeData()
107 if (pAccShape)
109 pAccShape->dispose();
110 pAccShape->release();
114 struct ScShapeDataLess
116 OUString msLayerId;
117 OUString msZOrder;
118 ScShapeDataLess()
119 : msLayerId( "LayerID" ),
120 msZOrder( "ZOrder" )
123 void ConvertLayerId(sal_Int16& rLayerID) const // changes the number of the LayerId so it the accessibility order
125 switch (rLayerID)
127 case SC_LAYER_FRONT:
128 rLayerID = 1;
129 break;
130 case SC_LAYER_BACK:
131 rLayerID = 0;
132 break;
133 case SC_LAYER_INTERN:
134 rLayerID = 2;
135 break;
136 case SC_LAYER_CONTROLS:
137 rLayerID = 3;
138 break;
141 sal_Bool LessThanSheet(const ScAccessibleShapeData* pData) const
143 sal_Bool bResult(false);
144 uno::Reference< beans::XPropertySet> xProps(pData->xShape, uno::UNO_QUERY);
145 if (xProps.is())
147 uno::Any aPropAny = xProps->getPropertyValue(msLayerId);
148 sal_Int16 nLayerID = 0;
149 if( (aPropAny >>= nLayerID) )
151 if (nLayerID == SC_LAYER_BACK)
152 bResult = sal_True;
155 return bResult;
157 sal_Bool operator()(const ScAccessibleShapeData* pData1, const ScAccessibleShapeData* pData2) const
159 sal_Bool bResult(false);
160 if (pData1 && pData2)
162 uno::Reference< beans::XPropertySet> xProps1(pData1->xShape, uno::UNO_QUERY);
163 uno::Reference< beans::XPropertySet> xProps2(pData2->xShape, uno::UNO_QUERY);
164 if (xProps1.is() && xProps2.is())
166 uno::Any aPropAny1 = xProps1->getPropertyValue(msLayerId);
167 uno::Any aPropAny2 = xProps2->getPropertyValue(msLayerId);
168 sal_Int16 nLayerID1(0);
169 sal_Int16 nLayerID2(0);
170 if( (aPropAny1 >>= nLayerID1) && (aPropAny2 >>= nLayerID2) )
172 if (nLayerID1 == nLayerID2)
174 uno::Any aAny1 = xProps1->getPropertyValue(msZOrder);
175 sal_Int32 nZOrder1 = 0;
176 uno::Any aAny2 = xProps2->getPropertyValue(msZOrder);
177 sal_Int32 nZOrder2 = 0;
178 if ( (aAny1 >>= nZOrder1) && (aAny2 >>= nZOrder2) )
179 bResult = (nZOrder1 < nZOrder2);
181 else
183 ConvertLayerId(nLayerID1);
184 ConvertLayerId(nLayerID2);
185 bResult = (nLayerID1 < nLayerID2);
190 else if (pData1 && !pData2)
191 bResult = LessThanSheet(pData1);
192 else if (!pData1 && pData2)
193 bResult = !LessThanSheet(pData2);
194 else
195 bResult = false;
196 return bResult;
200 struct DeselectShape
202 void operator() (const ScAccessibleShapeData* pAccShapeData) const
204 if (pAccShapeData)
206 pAccShapeData->bSelected = false;
207 if (pAccShapeData->pAccShape)
208 pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED);
213 struct SelectShape
215 uno::Reference < drawing::XShapes > xShapes;
216 SelectShape(uno::Reference<drawing::XShapes>& xTemp) : xShapes(xTemp) {}
217 void operator() (const ScAccessibleShapeData* pAccShapeData) const
219 if (pAccShapeData && pAccShapeData->bSelectable)
221 pAccShapeData->bSelected = sal_True;
222 if (pAccShapeData->pAccShape)
223 pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED);
224 if (xShapes.is())
225 xShapes->add(pAccShapeData->xShape);
230 struct Destroy
232 void operator() (ScAccessibleShapeData* pData)
234 if (pData)
235 DELETEZ(pData);
239 class ScChildrenShapes : public SfxListener,
240 public ::accessibility::IAccessibleParent
242 public:
243 ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
244 ~ScChildrenShapes();
246 ///===== SfxListener =====================================================
248 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
250 ///===== IAccessibleParent ===============================================
252 virtual sal_Bool ReplaceChild (
253 ::accessibility::AccessibleShape* pCurrentChild,
254 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
255 const long _nIndex,
256 const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
257 ) throw (::com::sun::star::uno::RuntimeException);
259 ///===== Internal ========================================================
260 void SetDrawBroadcaster();
262 sal_Int32 GetCount() const;
263 uno::Reference< XAccessible > Get(const ScAccessibleShapeData* pData) const;
264 uno::Reference< XAccessible > Get(sal_Int32 nIndex) const;
265 uno::Reference< XAccessible > GetAt(const awt::Point& rPoint) const;
267 // gets the index of the shape starting on 0 (without the index of the table)
268 // returns the selected shape
269 sal_Bool IsSelected(sal_Int32 nIndex,
270 com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape) const;
272 sal_Bool SelectionChanged();
274 void Select(sal_Int32 nIndex);
275 void DeselectAll(); // deselect also the table
276 void SelectAll();
277 sal_Int32 GetSelectedCount() const;
278 uno::Reference< XAccessible > GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const;
279 void Deselect(sal_Int32 nChildIndex);
281 SdrPage* GetDrawPage() const;
283 utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;
285 void VisAreaChanged() const;
286 private:
287 typedef std::vector<ScAccessibleShapeData*> SortedShapes;
289 mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order
291 mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo;
292 mutable com::sun::star::uno::Reference<com::sun::star::view::XSelectionSupplier> xSelectionSupplier;
293 mutable sal_uInt32 mnSdrObjCount;
294 mutable sal_uInt32 mnShapesSelected;
295 ScTabViewShell* mpViewShell;
296 ScAccessibleDocument* mpAccessibleDocument;
297 ScSplitPos meSplitPos;
299 void FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const;
300 sal_Bool FindSelectedShapesChanges(const com::sun::star::uno::Reference<com::sun::star::drawing::XShapes>& xShapes, sal_Bool bCommitChange) const;
301 void FillSelectionSupplier() const;
303 ScAddress* GetAnchor(const uno::Reference<drawing::XShape>& xShape) const;
304 uno::Reference<XAccessibleRelationSet> GetRelationSet(const ScAccessibleShapeData* pData) const;
305 void CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const;
306 void SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const;
307 void AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const;
308 void RemoveShape(const uno::Reference<drawing::XShape>& xShape) const;
310 sal_Bool FindShape(const uno::Reference<drawing::XShape>& xShape, SortedShapes::iterator& rItr) const;
312 sal_Int8 Compare(const ScAccessibleShapeData* pData1,
313 const ScAccessibleShapeData* pData2) const;
316 ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
318 mnShapesSelected(0),
319 mpViewShell(pViewShell),
320 mpAccessibleDocument(pAccessibleDocument),
321 meSplitPos(eSplitPos)
323 FillSelectionSupplier();
324 maZOrderedShapes.push_back(NULL); // add an element which represents the table
326 GetCount(); // fill list with filtered shapes (no internal shapes)
328 if (mnShapesSelected)
330 //set flag on every selected shape
331 if (!xSelectionSupplier.is())
332 throw uno::RuntimeException();
334 uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
335 if (xShapes.is())
336 FindSelectedShapesChanges(xShapes, false);
338 if (pViewShell)
340 ScViewData *pViewData = pViewShell->GetViewData();
341 SfxBroadcaster* pDrawBC = pViewData ? pViewData->GetDocument()->GetDrawBroadcaster() : NULL;
342 if (pDrawBC)
344 StartListening(*pDrawBC);
346 maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewData->GetDocument()->GetDrawLayer()) );
347 maShapeTreeInfo.SetSdrView(pViewData->GetScDrawView());
348 maShapeTreeInfo.SetController(NULL);
349 maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos));
350 maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
355 ScChildrenShapes::~ScChildrenShapes()
357 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy());
358 if (mpViewShell)
360 ScViewData *pViewData = mpViewShell->GetViewData();
361 SfxBroadcaster* pDrawBC = pViewData ? pViewData->GetDocument()->GetDrawBroadcaster() : NULL;
362 if (pDrawBC)
363 EndListening(*pDrawBC);
367 void ScChildrenShapes::SetDrawBroadcaster()
369 if (mpViewShell)
371 ScViewData *pViewData = mpViewShell->GetViewData();
372 SfxBroadcaster* pDrawBC = pViewData ? pViewData->GetDocument()->GetDrawBroadcaster() : NULL;
373 if (pDrawBC)
375 StartListening(*pDrawBC, sal_True);
377 maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewData->GetDocument()->GetDrawLayer()) );
378 maShapeTreeInfo.SetSdrView(pViewData->GetScDrawView());
379 maShapeTreeInfo.SetController(NULL);
380 maShapeTreeInfo.SetWindow(mpViewShell->GetWindowByPos(meSplitPos));
381 maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
386 void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint)
388 if ( rHint.ISA( SdrHint ) )
390 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
391 if (pSdrHint)
393 SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
394 if (pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->GetPage() == GetDrawPage()) &&
395 (pObj->GetPage() == pObj->GetObjList()) ) //only do something if the object lies direct on the page
397 switch (pSdrHint->GetKind())
399 case HINT_OBJCHG : // Objekt geaendert
401 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
402 if (xShape.is())
404 ScShapeDataLess aLess;
405 std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), aLess); // sort, because the z index or layer could be changed
406 CheckWhetherAnchorChanged(xShape);
409 break;
410 case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
412 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
413 if (xShape.is())
414 AddShape(xShape, sal_True);
416 break;
417 case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
419 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
420 if (xShape.is())
421 RemoveShape(xShape);
423 break;
424 default :
426 // other events are not interesting
428 break;
435 sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurrentChild,
436 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
437 const long _nIndex, const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo)
438 throw (uno::RuntimeException)
440 // create the new child
441 ::accessibility::AccessibleShape* pReplacement = ::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
442 ::accessibility::AccessibleShapeInfo ( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex ),
443 _rShapeTreeInfo
445 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pReplacement ); // keep this alive (do this before calling Init!)
446 if ( pReplacement )
447 pReplacement->Init();
449 sal_Bool bResult(false);
450 if (pCurrentChild && pReplacement)
452 OSL_ENSURE(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted");
453 SortedShapes::iterator aItr;
454 FindShape(pCurrentChild->GetXShape(), aItr);
455 if (aItr != maZOrderedShapes.end() && (*aItr))
457 if ((*aItr)->pAccShape)
459 OSL_ENSURE((*aItr)->pAccShape == pCurrentChild, "wrong child found");
460 AccessibleEventObject aEvent;
461 aEvent.EventId = AccessibleEventId::CHILD;
462 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
463 aEvent.OldValue <<= uno::makeAny(uno::Reference<XAccessible>(pCurrentChild));
465 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
467 pCurrentChild->dispose();
469 (*aItr)->pAccShape = pReplacement;
470 AccessibleEventObject aEvent;
471 aEvent.EventId = AccessibleEventId::CHILD;
472 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
473 aEvent.NewValue <<= uno::makeAny(uno::Reference<XAccessible>(pReplacement));
475 mpAccessibleDocument->CommitChange(aEvent); // child is new - event
476 bResult = sal_True;
479 return bResult;
482 sal_Int32 ScChildrenShapes::GetCount() const
484 SdrPage* pDrawPage = GetDrawPage();
485 if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in
487 mnSdrObjCount = pDrawPage->GetObjCount();
488 maZOrderedShapes.reserve(mnSdrObjCount + 1); // the table is always in
489 for (sal_uInt32 i = 0; i < mnSdrObjCount; ++i)
491 SdrObject* pObj = pDrawPage->GetObj(i);
492 if (pObj/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/)
494 uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY);
495 AddShape(xShape, false); //inserts in the correct order
499 return maZOrderedShapes.size();
502 uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
504 if (!pData)
505 return NULL;
507 if (!pData->pAccShape)
509 ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
510 ::accessibility::AccessibleShapeInfo aShapeInfo(pData->xShape, mpAccessibleDocument, const_cast<ScChildrenShapes*>(this));
511 pData->pAccShape = rShapeHandler.CreateAccessibleObject(
512 aShapeInfo, maShapeTreeInfo);
513 if (pData->pAccShape)
515 pData->pAccShape->acquire();
516 pData->pAccShape->Init();
517 if (pData->bSelected)
518 pData->pAccShape->SetState(AccessibleStateType::SELECTED);
519 if (!pData->bSelectable)
520 pData->pAccShape->ResetState(AccessibleStateType::SELECTABLE);
521 pData->pAccShape->SetRelationSet(GetRelationSet(pData));
524 return pData->pAccShape;
527 uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const
529 if (maZOrderedShapes.size() <= 1)
530 GetCount(); // fill list with filtered shapes (no internal shapes)
532 if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size())
533 return NULL;
535 return Get(maZOrderedShapes[nIndex]);
538 uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint) const
540 uno::Reference<XAccessible> xAccessible;
541 if(mpViewShell)
543 sal_Int32 i(maZOrderedShapes.size() - 1);
544 sal_Bool bFound(false);
545 while (!bFound && i >= 0)
547 ScAccessibleShapeData* pShape = maZOrderedShapes[i];
548 if (pShape)
550 if (!pShape->pAccShape)
551 Get(pShape);
553 if (pShape->pAccShape)
555 Point aPoint(VCLPoint(rPoint));
556 aPoint -= VCLRectangle(pShape->pAccShape->getBounds()).TopLeft();
557 if (pShape->pAccShape->containsPoint(AWTPoint(aPoint)))
559 xAccessible = pShape->pAccShape;
560 bFound = sal_True;
563 else
565 OSL_FAIL("I should have an accessible shape now!");
568 else
569 bFound = sal_True; // this is the sheet and it lies before the rest of the shapes which are background shapes
571 --i;
574 return xAccessible;
577 sal_Bool ScChildrenShapes::IsSelected(sal_Int32 nIndex,
578 uno::Reference<drawing::XShape>& rShape) const
580 sal_Bool bResult (false);
581 if (maZOrderedShapes.size() <= 1)
582 GetCount(); // fill list with filtered shapes (no internal shapes)
584 if (!xSelectionSupplier.is())
585 throw uno::RuntimeException();
587 if (!maZOrderedShapes[nIndex])
588 return false;
590 bResult = maZOrderedShapes[nIndex]->bSelected;
591 rShape = maZOrderedShapes[nIndex]->xShape;
593 #if OSL_DEBUG_LEVEL > 0 // test whether it is truly selected by a slower method
594 uno::Reference< drawing::XShape > xReturnShape;
595 sal_Bool bDebugResult(false);
596 uno::Reference<container::XIndexAccess> xIndexAccess;
597 xSelectionSupplier->getSelection() >>= xIndexAccess;
599 if (xIndexAccess.is())
601 sal_Int32 nCount(xIndexAccess->getCount());
602 if (nCount)
604 uno::Reference< drawing::XShape > xShape;
605 uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape;
606 sal_Int32 i(0);
607 while (!bDebugResult && (i < nCount))
609 xIndexAccess->getByIndex(i) >>= xShape;
610 if (xShape.is() && (xIndexShape.get() == xShape.get()))
612 bDebugResult = sal_True;
613 xReturnShape = xShape;
615 else
616 ++i;
620 OSL_ENSURE((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result");
621 #endif
623 return bResult;
626 sal_Bool ScChildrenShapes::SelectionChanged()
628 sal_Bool bResult(false);
629 if (!xSelectionSupplier.is())
630 throw uno::RuntimeException();
632 uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
634 bResult = FindSelectedShapesChanges(xShapes, sal_True);
636 return bResult;
639 void ScChildrenShapes::Select(sal_Int32 nIndex)
641 if (maZOrderedShapes.size() <= 1)
642 GetCount(); // fill list with filtered shapes (no internal shapes)
644 if (!xSelectionSupplier.is())
645 throw uno::RuntimeException();
647 if (!maZOrderedShapes[nIndex])
648 return;
650 uno::Reference<drawing::XShape> xShape;
651 if (!IsSelected(nIndex, xShape) && maZOrderedShapes[nIndex]->bSelectable)
653 uno::Reference<drawing::XShapes> xShapes;
654 xSelectionSupplier->getSelection() >>= xShapes;
656 if (!xShapes.is())
657 xShapes = new SvxShapeCollection();
659 xShapes->add(maZOrderedShapes[nIndex]->xShape);
663 xSelectionSupplier->select(uno::makeAny(xShapes));
664 maZOrderedShapes[nIndex]->bSelected = sal_True;
665 if (maZOrderedShapes[nIndex]->pAccShape)
666 maZOrderedShapes[nIndex]->pAccShape->SetState(AccessibleStateType::SELECTED);
668 catch (lang::IllegalArgumentException&)
674 void ScChildrenShapes::DeselectAll()
676 if (!xSelectionSupplier.is())
677 throw uno::RuntimeException();
679 sal_Bool bSomethingSelected(sal_True);
682 xSelectionSupplier->select(uno::Any()); //deselects all
684 catch (lang::IllegalArgumentException&)
686 OSL_FAIL("nothing selected before");
687 bSomethingSelected = false;
690 if (bSomethingSelected)
691 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), DeselectShape());
694 void ScChildrenShapes::SelectAll()
696 if (!xSelectionSupplier.is())
697 throw uno::RuntimeException();
699 if (maZOrderedShapes.size() <= 1)
700 GetCount(); // fill list with filtered shapes (no internal shapes)
702 if (maZOrderedShapes.size() > 1)
704 uno::Reference<drawing::XShapes> xShapes;
705 xShapes = new SvxShapeCollection();
709 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), SelectShape(xShapes));
710 xSelectionSupplier->select(uno::makeAny(xShapes));
712 catch (lang::IllegalArgumentException&)
714 SelectionChanged(); // find all selected shapes and set the flags
719 void ScChildrenShapes::FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const
721 uno::Reference<container::XIndexAccess> xIndexAccess;
722 xSelectionSupplier->getSelection() >>= xIndexAccess;
724 if (xIndexAccess.is())
726 sal_uInt32 nCount(xIndexAccess->getCount());
727 for (sal_uInt32 i = 0; i < nCount; ++i)
729 uno::Reference<drawing::XShape> xShape;
730 xIndexAccess->getByIndex(i) >>= xShape;
731 if (xShape.is())
732 rShapes.push_back(xShape);
737 sal_Int32 ScChildrenShapes::GetSelectedCount() const
739 if (!xSelectionSupplier.is())
740 throw uno::RuntimeException();
742 std::vector < uno::Reference < drawing::XShape > > aShapes;
743 FillShapes(aShapes);
745 return aShapes.size();
748 uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const
750 uno::Reference< XAccessible > xAccessible;
752 if (maZOrderedShapes.size() <= 1)
753 GetCount(); // fill list with shapes
755 if (!bTabSelected)
757 std::vector < uno::Reference < drawing::XShape > > aShapes;
758 FillShapes(aShapes);
760 SortedShapes::iterator aItr;
761 if (FindShape(aShapes[nSelectedChildIndex], aItr))
762 xAccessible = Get(aItr - maZOrderedShapes.begin());
764 else
766 SortedShapes::iterator aItr = maZOrderedShapes.begin();
767 SortedShapes::iterator aEndItr = maZOrderedShapes.end();
768 sal_Bool bFound(false);
769 while(!bFound && aItr != aEndItr)
771 if (*aItr)
773 if ((*aItr)->bSelected)
775 if (nSelectedChildIndex == 0)
776 bFound = sal_True;
777 else
778 --nSelectedChildIndex;
781 else
783 if (nSelectedChildIndex == 0)
784 bFound = sal_True;
785 else
786 --nSelectedChildIndex;
788 if (!bFound)
789 ++aItr;
791 if (bFound && *aItr)
792 xAccessible = (*aItr)->pAccShape;
795 return xAccessible;
798 void ScChildrenShapes::Deselect(sal_Int32 nChildIndex)
800 uno::Reference<drawing::XShape> xShape;
801 if (IsSelected(nChildIndex, xShape)) // returns false if it is the sheet
803 if (xShape.is())
805 uno::Reference<drawing::XShapes> xShapes;
806 xSelectionSupplier->getSelection() >>= xShapes;
807 if (xShapes.is())
808 xShapes->remove(xShape);
812 xSelectionSupplier->select(uno::makeAny(xShapes));
814 catch (lang::IllegalArgumentException&)
816 OSL_FAIL("something not selectable");
819 maZOrderedShapes[nChildIndex]->bSelected = false;
820 if (maZOrderedShapes[nChildIndex]->pAccShape)
821 maZOrderedShapes[nChildIndex]->pAccShape->ResetState(AccessibleStateType::SELECTED);
827 SdrPage* ScChildrenShapes::GetDrawPage() const
829 SCTAB nTab(mpAccessibleDocument->getVisibleTable());
830 SdrPage* pDrawPage = NULL;
831 if (mpViewShell)
833 ScViewData *pViewData = mpViewShell->GetViewData();
834 ScDocument* pDoc = pViewData ? pViewData->GetDocument() : NULL;
835 if (pDoc && pDoc->GetDrawLayer())
837 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
838 if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
839 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
842 return pDrawPage;
845 struct SetRelation
847 const ScChildrenShapes* mpChildrenShapes;
848 mutable utl::AccessibleRelationSetHelper* mpRelationSet;
849 const ScAddress* mpAddress;
850 SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress)
852 mpChildrenShapes(pChildrenShapes),
853 mpRelationSet(NULL),
854 mpAddress(pAddress)
857 void operator() (const ScAccessibleShapeData* pAccShapeData) const
859 if (pAccShapeData &&
860 ((!pAccShapeData->pRelationCell && !mpAddress) ||
861 (pAccShapeData->pRelationCell && mpAddress && (*(pAccShapeData->pRelationCell) == *mpAddress))))
863 if (!mpRelationSet)
864 mpRelationSet = new utl::AccessibleRelationSetHelper();
866 AccessibleRelation aRelation;
867 aRelation.TargetSet.realloc(1);
868 aRelation.TargetSet[0] = mpChildrenShapes->Get(pAccShapeData);
869 aRelation.RelationType = AccessibleRelationType::CONTROLLER_FOR;
871 mpRelationSet->AddRelation(aRelation);
876 utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const
878 SetRelation aSetRelation(this, pAddress);
879 ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation);
880 return aSetRelation.mpRelationSet;
883 sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, sal_Bool /* bCommitChange */) const
885 sal_Bool bResult(false);
886 SortedShapes aShapesList;
887 uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY);
888 if (xIndexAcc.is())
890 mnShapesSelected = xIndexAcc->getCount();
891 for (sal_uInt32 i = 0; i < mnShapesSelected; ++i)
893 uno::Reference< drawing::XShape > xShape;
894 xIndexAcc->getByIndex(i) >>= xShape;
895 if (xShape.is())
897 ScAccessibleShapeData* pShapeData = new ScAccessibleShapeData();
898 pShapeData->xShape = xShape;
899 aShapesList.push_back(pShapeData);
903 else
904 mnShapesSelected = 0;
905 ScShapeDataLess aLess;
906 std::sort(aShapesList.begin(), aShapesList.end(), aLess);
908 SortedShapes::iterator aXShapesItr(aShapesList.begin());
909 SortedShapes::const_iterator aXShapesEndItr(aShapesList.end());
910 SortedShapes::iterator aDataItr(maZOrderedShapes.begin());
911 SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end());
912 SortedShapes::const_iterator aFocusedItr = aDataEndItr;
913 while((aDataItr != aDataEndItr))
915 if (*aDataItr) // is it realy a shape or only the sheet
917 sal_Int8 nComp(0);
918 if (aXShapesItr == aXShapesEndItr)
919 nComp = -1; // simulate that the Shape is lower, so the selction state will be removed
920 else
921 nComp = Compare(*aDataItr, *aXShapesItr);
922 if (nComp == 0)
924 if (!(*aDataItr)->bSelected)
926 (*aDataItr)->bSelected = sal_True;
927 if ((*aDataItr)->pAccShape)
929 (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED);
930 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
931 bResult = sal_True;
933 aFocusedItr = aDataItr;
935 ++aDataItr;
936 ++aXShapesItr;
938 else if (nComp < 0)
940 if ((*aDataItr)->bSelected)
942 (*aDataItr)->bSelected = false;
943 if ((*aDataItr)->pAccShape)
945 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED);
946 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
947 bResult = sal_True;
950 ++aDataItr;
952 else
954 OSL_FAIL("here is a selected shape which is not in the childlist");
955 ++aXShapesItr;
956 --mnShapesSelected;
959 else
960 ++aDataItr;
962 if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1))
963 (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED);
965 std::for_each(aShapesList.begin(), aShapesList.end(), Destroy());
967 return bResult;
970 void ScChildrenShapes::FillSelectionSupplier() const
972 if (!xSelectionSupplier.is() && mpViewShell)
974 SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame();
975 if (pViewFrame)
977 xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY);
978 if (xSelectionSupplier.is())
980 if (mpAccessibleDocument)
981 xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument);
982 uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY);
983 if (xShapes.is())
984 mnShapesSelected = xShapes->getCount();
990 ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const
992 ScAddress* pAddress = NULL;
993 if (mpViewShell)
995 SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
996 uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY);
997 if (pShapeImp && xShapeProp.is())
999 if (SdrObject *pSdrObj = pShapeImp->GetSdrObject())
1001 if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjData(pSdrObj))
1002 return new ScAddress(pAnchor->maStart);
1007 return pAddress;
1010 uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const
1012 utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper();
1014 if(pData && pRelationSet && mpAccessibleDocument)
1016 uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table
1017 if (pData->pRelationCell && xAccessible.is())
1019 uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY);
1020 if (xAccTable.is())
1021 xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col());
1023 AccessibleRelation aRelation;
1024 aRelation.TargetSet.realloc(1);
1025 aRelation.TargetSet[0] = xAccessible;
1026 aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY;
1027 pRelationSet->AddRelation(aRelation);
1030 return pRelationSet;
1033 void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const
1035 SortedShapes::iterator aItr;
1036 if (FindShape(xShape, aItr))
1037 SetAnchor(xShape, *aItr);
1040 void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const
1042 if (pData)
1044 ScAddress* pAddress = GetAnchor(xShape);
1045 if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) ||
1046 (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell))
1048 if (pData->pRelationCell)
1049 delete pData->pRelationCell;
1050 pData->pRelationCell = pAddress;
1051 if (pData->pAccShape)
1052 pData->pAccShape->SetRelationSet(GetRelationSet(pData));
1054 else
1055 delete pAddress;
1059 void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const
1061 SortedShapes::iterator aFindItr;
1062 if (!FindShape(xShape, aFindItr))
1064 ScAccessibleShapeData* pShape = new ScAccessibleShapeData();
1065 pShape->xShape = xShape;
1066 SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape);
1067 SetAnchor(xShape, pShape);
1069 uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY);
1070 if (xShapeProp.is())
1072 uno::Any aPropAny = xShapeProp->getPropertyValue(OUString( "LayerID" ));
1073 sal_Int16 nLayerID = 0;
1074 if( aPropAny >>= nLayerID )
1076 if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
1077 pShape->bSelectable = false;
1078 else
1079 pShape->bSelectable = sal_True;
1084 if (!xSelectionSupplier.is())
1085 throw uno::RuntimeException();
1087 uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
1088 if (xEnumAcc.is())
1090 uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration();
1091 if (xEnum.is())
1093 uno::Reference<drawing::XShape> xSelectedShape;
1094 sal_Bool bFound(false);
1095 while (!bFound && xEnum->hasMoreElements())
1097 xEnum->nextElement() >>= xSelectedShape;
1098 if (xShape.is() && (xShape.get() == xSelectedShape.get()))
1100 pShape->bSelected = sal_True;
1101 bFound = sal_True;
1106 if (mpAccessibleDocument && bCommitChange)
1108 AccessibleEventObject aEvent;
1109 aEvent.EventId = AccessibleEventId::CHILD;
1110 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
1111 aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin());
1113 mpAccessibleDocument->CommitChange(aEvent); // new child - event
1116 else
1118 OSL_FAIL("shape is always in the list");
1122 void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const
1124 SortedShapes::iterator aItr;
1125 if (FindShape(xShape, aItr))
1127 if (mpAccessibleDocument)
1129 uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin()));
1131 delete *aItr;
1132 maZOrderedShapes.erase(aItr);
1134 AccessibleEventObject aEvent;
1135 aEvent.EventId = AccessibleEventId::CHILD;
1136 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
1137 aEvent.OldValue <<= uno::makeAny(xOldAccessible);
1139 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
1141 else
1143 delete *aItr;
1144 maZOrderedShapes.erase(aItr);
1147 else
1149 OSL_FAIL("shape was not in internal list");
1153 sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const
1155 sal_Bool bResult(false);
1156 ScAccessibleShapeData aShape;
1157 aShape.xShape = xShape;
1158 ScShapeDataLess aLess;
1159 rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess);
1160 if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get()))
1161 bResult = sal_True; // if the shape is found
1163 #if OSL_DEBUG_LEVEL > 0 // test whether it finds truly the correct shape (perhaps it is not really sorted)
1164 SortedShapes::iterator aDebugItr = maZOrderedShapes.begin();
1165 SortedShapes::iterator aEndItr = maZOrderedShapes.end();
1166 sal_Bool bFound(false);
1167 while (!bFound && aDebugItr != aEndItr)
1169 if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get()))
1170 bFound = sal_True;
1171 else
1172 ++aDebugItr;
1174 sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end());
1175 OSL_ENSURE((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found");
1176 #endif
1177 return bResult;
1180 sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1,
1181 const ScAccessibleShapeData* pData2) const
1183 ScShapeDataLess aLess;
1185 sal_Bool bResult1(aLess(pData1, pData2));
1186 sal_Bool bResult2(aLess(pData2, pData1));
1188 sal_Int8 nResult(0);
1189 if (!bResult1 && bResult2)
1190 nResult = 1;
1191 else if (bResult1 && !bResult2)
1192 nResult = -1;
1194 return nResult;
1197 struct ScVisAreaChanged
1199 ScAccessibleDocument* mpAccDoc;
1200 ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {}
1201 void operator() (const ScAccessibleShapeData* pAccShapeData) const
1203 if (pAccShapeData && pAccShapeData->pAccShape)
1205 pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc);
1210 void ScChildrenShapes::VisAreaChanged() const
1212 ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument);
1213 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged);
1216 // ============================================================================
1218 ScAccessibleDocument::ScAccessibleDocument(
1219 const uno::Reference<XAccessible>& rxParent,
1220 ScTabViewShell* pViewShell,
1221 ScSplitPos eSplitPos)
1222 : ScAccessibleDocumentBase(rxParent),
1223 mpViewShell(pViewShell),
1224 meSplitPos(eSplitPos),
1225 mpAccessibleSpreadsheet(NULL),
1226 mpChildrenShapes(NULL),
1227 mpTempAccEdit(NULL),
1228 mbCompleteSheetSelected(false)
1230 if (pViewShell)
1232 pViewShell->AddAccessibilityObject(*this);
1233 Window *pWin = pViewShell->GetWindowByPos(eSplitPos);
1234 if( pWin )
1236 pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1237 sal_uInt16 nCount = pWin->GetChildCount();
1238 for( sal_uInt16 i=0; i < nCount; ++i )
1240 Window *pChildWin = pWin->GetChild( i );
1241 if( pChildWin &&
1242 AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1243 AddChild( pChildWin->GetAccessible(), false );
1246 ScViewData *pViewData = pViewShell->GetViewData();
1247 if (pViewData && pViewData->HasEditView(eSplitPos))
1249 uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewData->GetEditView(eSplitPos),
1250 pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(),
1251 ScAccessibleEditObject::CellInEditMode);
1252 AddChild(xAcc, false);
1255 maVisArea = GetVisibleArea_Impl();
1258 void ScAccessibleDocument::Init()
1260 if(!mpChildrenShapes)
1261 mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos);
1264 ScAccessibleDocument::~ScAccessibleDocument(void)
1266 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
1268 // increment refcount to prevent double call off dtor
1269 osl_atomic_increment( &m_refCount );
1270 dispose();
1274 void SAL_CALL ScAccessibleDocument::disposing()
1276 SolarMutexGuard aGuard;
1277 FreeAccessibleSpreadsheet();
1278 if (mpViewShell)
1280 Window *pWin = mpViewShell->GetWindowByPos(meSplitPos);
1281 if( pWin )
1282 pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1284 mpViewShell->RemoveAccessibilityObject(*this);
1285 mpViewShell = NULL;
1287 if (mpChildrenShapes)
1288 DELETEZ(mpChildrenShapes);
1290 ScAccessibleDocumentBase::disposing();
1293 void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ )
1294 throw (uno::RuntimeException)
1296 disposing();
1299 //===== SfxListener =====================================================
1301 IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
1303 OSL_ENSURE( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
1304 if ( pEvent && pEvent->ISA( VclWindowEvent ) )
1306 VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
1307 OSL_ENSURE( pVclEvent->GetWindow(), "Window???" );
1308 switch ( pVclEvent->GetId() )
1310 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
1312 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
1313 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1315 AddChild( pChildWin->GetAccessible(), sal_True );
1318 break;
1319 case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children
1321 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
1322 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1324 RemoveChild( pChildWin->GetAccessible(), sal_True );
1327 break;
1330 return 0;
1333 void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1335 if (rHint.ISA( ScAccGridWinFocusLostHint ) )
1337 const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint;
1338 if (rRef.GetOldGridWin() == meSplitPos)
1340 if (mxTempAcc.is() && mpTempAccEdit)
1341 mpTempAccEdit->LostFocus();
1342 else if (mpAccessibleSpreadsheet)
1343 mpAccessibleSpreadsheet->LostFocus();
1344 else
1345 CommitFocusLost();
1348 else if (rHint.ISA( ScAccGridWinFocusGotHint ) )
1350 const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint;
1351 if (rRef.GetNewGridWin() == meSplitPos)
1353 if (mxTempAcc.is() && mpTempAccEdit)
1354 mpTempAccEdit->GotFocus();
1355 else if (mpAccessibleSpreadsheet)
1356 mpAccessibleSpreadsheet->GotFocus();
1357 else
1358 CommitFocusGained();
1361 else if (rHint.ISA( SfxSimpleHint ))
1363 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
1364 // only notify if child exist, otherwise it is not necessary
1365 if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
1366 mpAccessibleSpreadsheet)
1368 FreeAccessibleSpreadsheet();
1369 if (mpChildrenShapes)
1370 DELETEZ(mpChildrenShapes);
1372 // Accessibility: Shapes / form controls after reload not accessible
1373 if ( !mpChildrenShapes )
1375 mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos );
1378 AccessibleEventObject aEvent;
1379 aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN;
1380 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1381 CommitChange(aEvent); // all children changed
1383 else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
1385 if (mpChildrenShapes)
1386 mpChildrenShapes->SetDrawBroadcaster();
1388 else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell
1390 ScViewData *pViewData = mpViewShell ? mpViewShell->GetViewData() : NULL;
1391 if (pViewData && pViewData->HasEditView(meSplitPos))
1393 mpTempAccEdit = new ScAccessibleEditObject(this, pViewData->GetEditView(meSplitPos),
1394 mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(),
1395 OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), ScAccessibleEditObject::CellInEditMode);
1396 uno::Reference<XAccessible> xAcc = mpTempAccEdit;
1398 AddChild(xAcc, sal_True);
1400 if (mpAccessibleSpreadsheet)
1401 mpAccessibleSpreadsheet->LostFocus();
1402 else
1403 CommitFocusLost();
1405 mpTempAccEdit->GotFocus();
1408 else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE)
1410 if (mxTempAcc.is())
1412 if (mpTempAccEdit)
1413 mpTempAccEdit->LostFocus();
1415 mpTempAccEdit = NULL;
1416 RemoveChild(mxTempAcc, sal_True);
1418 if (mpAccessibleSpreadsheet)
1419 mpAccessibleSpreadsheet->GotFocus();
1420 else
1421 CommitFocusGained();
1424 else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED))
1426 Rectangle aOldVisArea(maVisArea);
1427 maVisArea = GetVisibleArea_Impl();
1429 if (maVisArea != aOldVisArea)
1431 if (maVisArea.GetSize() != aOldVisArea.GetSize())
1433 AccessibleEventObject aEvent;
1434 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
1435 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1437 CommitChange(aEvent);
1439 if (mpAccessibleSpreadsheet)
1440 mpAccessibleSpreadsheet->BoundingBoxChanged();
1442 else if (mpAccessibleSpreadsheet)
1444 mpAccessibleSpreadsheet->VisAreaChanged();
1446 if (mpChildrenShapes)
1447 mpChildrenShapes->VisAreaChanged();
1452 ScAccessibleDocumentBase::Notify(rBC, rHint);
1455 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
1456 throw (uno::RuntimeException)
1458 sal_Bool bSelectionChanged(false);
1459 if (mpAccessibleSpreadsheet)
1461 sal_Bool bOldSelected(mbCompleteSheetSelected);
1462 mbCompleteSheetSelected = IsTableSelected();
1463 if (bOldSelected != mbCompleteSheetSelected)
1465 mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
1466 bSelectionChanged = sal_True;
1470 if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
1471 bSelectionChanged = sal_True;
1473 if (bSelectionChanged)
1475 AccessibleEventObject aEvent;
1476 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1477 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1479 CommitChange(aEvent);
1483 //===== XInterface =====================================================
1485 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
1486 throw (uno::RuntimeException)
1488 uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
1489 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
1492 void SAL_CALL ScAccessibleDocument::acquire()
1493 throw ()
1495 ScAccessibleContextBase::acquire();
1498 void SAL_CALL ScAccessibleDocument::release()
1499 throw ()
1501 ScAccessibleContextBase::release();
1504 //===== XAccessibleComponent ============================================
1506 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint(
1507 const awt::Point& rPoint )
1508 throw (uno::RuntimeException)
1510 uno::Reference<XAccessible> xAccessible = NULL;
1511 if (containsPoint(rPoint))
1513 SolarMutexGuard aGuard;
1514 IsObjectValid();
1515 if (mpChildrenShapes)
1516 xAccessible = mpChildrenShapes->GetAt(rPoint);
1517 if(!xAccessible.is())
1519 if (mxTempAcc.is())
1521 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext());
1522 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY);
1523 if (xComp.is())
1525 Rectangle aBound(VCLRectangle(xComp->getBounds()));
1526 if (aBound.IsInside(VCLPoint(rPoint)))
1527 xAccessible = mxTempAcc;
1530 if (!xAccessible.is())
1531 xAccessible = GetAccessibleSpreadsheet();
1534 return xAccessible;
1537 void SAL_CALL ScAccessibleDocument::grabFocus( )
1538 throw (uno::RuntimeException)
1540 SolarMutexGuard aGuard;
1541 IsObjectValid();
1542 if (getAccessibleParent().is())
1544 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1545 if (xAccessibleComponent.is())
1547 xAccessibleComponent->grabFocus();
1548 // grab only focus if it does not have the focus and it is not hidden
1549 if (mpViewShell && mpViewShell->GetViewData() &&
1550 (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
1551 mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
1553 mpViewShell->ActivatePart(meSplitPos);
1559 //===== XAccessibleContext ==============================================
1561 /// Return the number of currently visible children.
1562 sal_Int32 SAL_CALL
1563 ScAccessibleDocument::getAccessibleChildCount(void)
1564 throw (uno::RuntimeException)
1566 SolarMutexGuard aGuard;
1567 IsObjectValid();
1568 sal_Int32 nCount(1);
1569 if (mpChildrenShapes)
1570 nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
1572 if (mxTempAcc.is())
1573 ++nCount;
1575 return nCount;
1578 /// Return the specified child or NULL if index is invalid.
1579 uno::Reference<XAccessible> SAL_CALL
1580 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex)
1581 throw (uno::RuntimeException,
1582 lang::IndexOutOfBoundsException)
1584 SolarMutexGuard aGuard;
1585 IsObjectValid();
1586 uno::Reference<XAccessible> xAccessible;
1587 if (nIndex >= 0)
1589 sal_Int32 nCount(1);
1590 if (mpChildrenShapes)
1592 xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
1593 nCount = mpChildrenShapes->GetCount(); //there is always a table
1595 if (!xAccessible.is())
1597 if (nIndex < nCount)
1598 xAccessible = GetAccessibleSpreadsheet();
1599 else if (nIndex == nCount && mxTempAcc.is())
1600 xAccessible = mxTempAcc;
1604 if (!xAccessible.is())
1605 throw lang::IndexOutOfBoundsException();
1607 return xAccessible;
1610 /// Return the set of current states.
1611 uno::Reference<XAccessibleStateSet> SAL_CALL
1612 ScAccessibleDocument::getAccessibleStateSet(void)
1613 throw (uno::RuntimeException)
1615 SolarMutexGuard aGuard;
1616 uno::Reference<XAccessibleStateSet> xParentStates;
1617 if (getAccessibleParent().is())
1619 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1620 xParentStates = xParentContext->getAccessibleStateSet();
1622 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1623 if (IsDefunc(xParentStates))
1624 pStateSet->AddState(AccessibleStateType::DEFUNC);
1625 else
1627 if (IsEditable(xParentStates))
1628 pStateSet->AddState(AccessibleStateType::EDITABLE);
1629 pStateSet->AddState(AccessibleStateType::ENABLED);
1630 pStateSet->AddState(AccessibleStateType::OPAQUE);
1631 if (isShowing())
1632 pStateSet->AddState(AccessibleStateType::SHOWING);
1633 if (isVisible())
1634 pStateSet->AddState(AccessibleStateType::VISIBLE);
1636 return pStateSet;
1639 ///===== XAccessibleSelection ===========================================
1641 void SAL_CALL
1642 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
1643 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1645 SolarMutexGuard aGuard;
1646 IsObjectValid();
1648 if (mpChildrenShapes && mpViewShell)
1650 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1651 if (mxTempAcc.is())
1652 ++nCount;
1653 if (nChildIndex < 0 || nChildIndex >= nCount)
1654 throw lang::IndexOutOfBoundsException();
1656 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1657 if (xAccessible.is())
1659 sal_Bool bWasTableSelected(IsTableSelected());
1661 if (mpChildrenShapes)
1662 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1664 if (bWasTableSelected)
1665 mpViewShell->SelectAll();
1667 else
1669 if (mpViewShell)
1670 mpViewShell->SelectAll();
1675 sal_Bool SAL_CALL
1676 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
1677 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1679 SolarMutexGuard aGuard;
1680 IsObjectValid();
1681 sal_Bool bResult(false);
1683 if (mpChildrenShapes)
1685 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1686 if (mxTempAcc.is())
1687 ++nCount;
1688 if (nChildIndex < 0 || nChildIndex >= nCount)
1689 throw lang::IndexOutOfBoundsException();
1691 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1692 if (xAccessible.is())
1694 uno::Reference<drawing::XShape> xShape;
1695 bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high
1697 else
1699 if (mxTempAcc.is() && nChildIndex == nCount)
1700 bResult = sal_True;
1701 else
1702 bResult = IsTableSelected();
1705 return bResult;
1708 void SAL_CALL
1709 ScAccessibleDocument::clearAccessibleSelection( )
1710 throw (uno::RuntimeException)
1712 SolarMutexGuard aGuard;
1713 IsObjectValid();
1715 if (mpChildrenShapes)
1716 mpChildrenShapes->DeselectAll(); //deselects all (also the table)
1719 void SAL_CALL
1720 ScAccessibleDocument::selectAllAccessibleChildren( )
1721 throw (uno::RuntimeException)
1723 SolarMutexGuard aGuard;
1724 IsObjectValid();
1726 if (mpChildrenShapes)
1727 mpChildrenShapes->SelectAll();
1729 // select table after shapes, because while selecting shapes the table will be deselected
1730 if (mpViewShell)
1732 mpViewShell->SelectAll();
1736 sal_Int32 SAL_CALL
1737 ScAccessibleDocument::getSelectedAccessibleChildCount( )
1738 throw (uno::RuntimeException)
1740 SolarMutexGuard aGuard;
1741 IsObjectValid();
1742 sal_Int32 nCount(0);
1744 if (mpChildrenShapes)
1745 nCount = mpChildrenShapes->GetSelectedCount();
1747 if (IsTableSelected())
1748 ++nCount;
1750 if (mxTempAcc.is())
1751 ++nCount;
1753 return nCount;
1756 uno::Reference<XAccessible > SAL_CALL
1757 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1758 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1760 SolarMutexGuard aGuard;
1761 IsObjectValid();
1762 uno::Reference<XAccessible> xAccessible;
1763 if (mpChildrenShapes)
1765 sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
1766 if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
1767 throw lang::IndexOutOfBoundsException();
1769 sal_Bool bTabMarked(IsTableSelected());
1771 if (mpChildrenShapes)
1772 xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
1773 if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
1774 xAccessible = mxTempAcc;
1775 else if (bTabMarked)
1776 xAccessible = GetAccessibleSpreadsheet();
1779 OSL_ENSURE(xAccessible.is(), "here should always be an accessible object or a exception throwed");
1781 return xAccessible;
1784 void SAL_CALL
1785 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
1786 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1788 SolarMutexGuard aGuard;
1789 IsObjectValid();
1791 if (mpChildrenShapes && mpViewShell)
1793 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1794 if (mxTempAcc.is())
1795 ++nCount;
1796 if (nChildIndex < 0 || nChildIndex >= nCount)
1797 throw lang::IndexOutOfBoundsException();
1799 sal_Bool bTabMarked(IsTableSelected());
1801 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1802 if (xAccessible.is())
1804 if (mpChildrenShapes)
1805 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1807 if (bTabMarked)
1808 mpViewShell->SelectAll(); // select the table again
1810 else if (bTabMarked)
1811 mpViewShell->Unmark();
1815 //===== XServiceInfo ====================================================
1817 OUString SAL_CALL
1818 ScAccessibleDocument::getImplementationName(void)
1819 throw (uno::RuntimeException)
1821 return OUString("ScAccessibleDocument");
1824 uno::Sequence< OUString> SAL_CALL
1825 ScAccessibleDocument::getSupportedServiceNames(void)
1826 throw (uno::RuntimeException)
1828 uno::Sequence< OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
1829 sal_Int32 nOldSize(aSequence.getLength());
1830 aSequence.realloc(nOldSize + 1);
1831 OUString* pNames = aSequence.getArray();
1833 pNames[nOldSize] = OUString("com.sun.star.AccessibleSpreadsheetDocumentView");
1835 return aSequence;
1838 //===== XTypeProvider =======================================================
1840 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
1841 throw (uno::RuntimeException)
1843 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
1846 namespace
1848 class theScAccessibleDocumentImplementationId : public rtl::Static< UnoTunnelIdInit, theScAccessibleDocumentImplementationId > {};
1851 uno::Sequence<sal_Int8> SAL_CALL
1852 ScAccessibleDocument::getImplementationId(void)
1853 throw (uno::RuntimeException)
1855 return theScAccessibleDocumentImplementationId::get().getSeq();
1858 ///===== IAccessibleViewForwarder ========================================
1860 sal_Bool ScAccessibleDocument::IsValid (void) const
1862 SolarMutexGuard aGuard;
1863 IsObjectValid();
1864 return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
1867 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
1869 Rectangle aVisRect(GetBoundingBox());
1871 if (mpViewShell)
1873 ScViewData *pViewData = mpViewShell->GetViewData();
1874 if (pViewData)
1876 Point aPoint(pViewData->GetPixPos(meSplitPos)); // returns a negative Point
1877 aPoint.setX(-aPoint.getX());
1878 aPoint.setY(-aPoint.getY());
1879 aVisRect.SetPos(aPoint);
1882 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1883 if (pWin)
1884 aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
1887 return aVisRect;
1890 Rectangle ScAccessibleDocument::GetVisibleArea() const
1892 SolarMutexGuard aGuard;
1893 IsObjectValid();
1894 return maVisArea;
1897 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
1899 SolarMutexGuard aGuard;
1900 IsObjectValid();
1901 Point aPoint;
1902 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1903 if (pWin)
1905 aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
1906 aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
1908 return aPoint;
1911 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
1913 SolarMutexGuard aGuard;
1914 IsObjectValid();
1915 Size aSize;
1916 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1917 if (pWin)
1918 aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
1919 return aSize;
1922 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
1924 SolarMutexGuard aGuard;
1925 IsObjectValid();
1926 Point aPoint;
1927 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1928 if (pWin)
1930 aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
1931 aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
1933 return aPoint;
1936 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
1938 SolarMutexGuard aGuard;
1939 IsObjectValid();
1940 Size aSize;
1941 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1942 if (pWin)
1943 aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
1944 return aSize;
1947 //===== internal ========================================================
1949 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
1951 utl::AccessibleRelationSetHelper* pRelationSet = NULL;
1952 if (mpChildrenShapes)
1953 pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
1954 return pRelationSet;
1957 OUString SAL_CALL
1958 ScAccessibleDocument::createAccessibleDescription(void)
1959 throw (uno::RuntimeException)
1961 OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR));
1962 return sDescription;
1965 OUString SAL_CALL
1966 ScAccessibleDocument::createAccessibleName(void)
1967 throw (uno::RuntimeException)
1969 SolarMutexGuard aGuard;
1970 IsObjectValid();
1971 OUString sName = String(ScResId(STR_ACC_DOC_NAME));
1972 sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
1973 sName += OUString::valueOf(nNumber);
1974 return sName;
1977 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
1978 throw (uno::RuntimeException)
1980 Rectangle aRect;
1981 if (mpViewShell)
1983 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
1984 if (pWindow)
1985 aRect = pWindow->GetWindowExtentsRelative(NULL);
1987 return aRect;
1990 Rectangle ScAccessibleDocument::GetBoundingBox() const
1991 throw (uno::RuntimeException)
1993 Rectangle aRect;
1994 if (mpViewShell)
1996 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
1997 if (pWindow)
1998 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
2000 return aRect;
2003 SCTAB ScAccessibleDocument::getVisibleTable() const
2005 SCTAB nVisibleTable(0);
2006 ScViewData *pViewData = mpViewShell ? mpViewShell->GetViewData() : NULL;
2007 if (pViewData)
2008 nVisibleTable = pViewData->GetTabNo();
2009 return nVisibleTable;
2012 uno::Reference < XAccessible >
2013 ScAccessibleDocument::GetAccessibleSpreadsheet()
2015 if (!mpAccessibleSpreadsheet && mpViewShell)
2017 mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
2018 mpAccessibleSpreadsheet->acquire();
2019 mpAccessibleSpreadsheet->Init();
2020 mbCompleteSheetSelected = IsTableSelected();
2022 return mpAccessibleSpreadsheet;
2025 void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2027 if (mpAccessibleSpreadsheet)
2029 mpAccessibleSpreadsheet->dispose();
2030 mpAccessibleSpreadsheet->release();
2031 mpAccessibleSpreadsheet = NULL;
2035 sal_Bool ScAccessibleDocument::IsTableSelected() const
2037 sal_Bool bResult (false);
2038 ScViewData *pViewData = mpViewShell ? mpViewShell->GetViewData() : NULL;
2039 if(pViewData)
2041 SCTAB nTab(getVisibleTable());
2042 //#103800#; use a copy of MarkData
2043 ScMarkData aMarkData(pViewData->GetMarkData());
2044 aMarkData.MarkToMulti();
2045 if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
2046 bResult = sal_True;
2048 return bResult;
2051 sal_Bool ScAccessibleDocument::IsDefunc(
2052 const uno::Reference<XAccessibleStateSet>& rxParentStates)
2054 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
2055 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
2058 sal_Bool ScAccessibleDocument::IsEditable(
2059 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
2061 // what is with document protection or readonly documents?
2062 return sal_True;
2065 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2067 OSL_ENSURE(!mxTempAcc.is(), "this object should be removed before");
2068 if (xAcc.is())
2070 mxTempAcc = xAcc;
2071 if( bFireEvent )
2073 AccessibleEventObject aEvent;
2074 aEvent.Source = uno::Reference<XAccessibleContext>(this);
2075 aEvent.EventId = AccessibleEventId::CHILD;
2076 aEvent.NewValue <<= mxTempAcc;
2077 CommitChange( aEvent );
2082 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2084 OSL_ENSURE(mxTempAcc.is(), "this object should be added before");
2085 if (xAcc.is())
2087 OSL_ENSURE(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
2088 if( bFireEvent )
2090 AccessibleEventObject aEvent;
2091 aEvent.Source = uno::Reference<XAccessibleContext>(this);
2092 aEvent.EventId = AccessibleEventId::CHILD;
2093 aEvent.OldValue <<= mxTempAcc;
2094 CommitChange( aEvent );
2096 mxTempAcc = NULL;
2100 OUString ScAccessibleDocument::GetCurrentCellName() const
2102 String sName( ScResId(STR_ACC_CELL_NAME) );
2103 ScViewData *pViewData = mpViewShell ? mpViewShell->GetViewData() : NULL;
2104 if (pViewData)
2106 String sAddress;
2107 // Document not needed, because only the cell address, but not the tablename is needed
2108 pViewData->GetCurPos().Format( sAddress, SCA_VALID, NULL );
2109 sName.SearchAndReplaceAscii("%1", sAddress);
2111 return OUString(sName);
2114 OUString ScAccessibleDocument::GetCurrentCellDescription() const
2116 return OUString();
2119 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */