Update ooo320-m1
[ooovba.git] / sc / source / ui / Accessibility / AccessibleDocument.cxx
blobb16444b19b1cc5a07e3f51e899a3d2efae3560ba
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleDocument.cxx,v $
10 * $Revision: 1.76.40.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 #include "AccessibleDocument.hxx"
36 #include "AccessibleSpreadsheet.hxx"
37 #include "tabvwsh.hxx"
38 #include "AccessibilityHints.hxx"
39 #include "document.hxx"
40 #include "drwlayer.hxx"
41 #include "unoguard.hxx"
42 #include "shapeuno.hxx"
43 #include "DrawModelBroadcaster.hxx"
44 #include "drawview.hxx"
45 #include "gridwin.hxx"
46 #include "AccessibleEditObject.hxx"
47 #include "scresid.hxx"
48 #ifndef SC_SC_HRC
49 #include "sc.hrc"
50 #endif
51 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
52 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
53 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
54 #endif
55 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
56 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
57 #endif
58 #include <com/sun/star/view/XSelectionSupplier.hpp>
59 #include <com/sun/star/drawing/XShape.hpp>
60 #include <com/sun/star/drawing/XShapes.hpp>
62 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
63 #include <unotools/accessiblestatesethelper.hxx>
64 #endif
65 #include <tools/debug.hxx>
66 #include <tools/gen.hxx>
67 #include <svx/svdpage.hxx>
68 #include <svx/svdobj.hxx>
69 #include <svx/ShapeTypeHandler.hxx>
70 #include <svx/AccessibleShape.hxx>
71 #include <svx/AccessibleShapeTreeInfo.hxx>
72 #include <svx/AccessibleShapeInfo.hxx>
73 #include <comphelper/sequence.hxx>
74 #include <sfx2/viewfrm.hxx>
75 #include <svx/unoshcol.hxx>
76 #include <svx/unoshape.hxx>
77 #include <unotools/accessiblerelationsethelper.hxx>
78 #include <toolkit/helper/convert.hxx>
80 #include <list>
81 #include <algorithm>
83 using namespace ::com::sun::star;
84 using namespace ::com::sun::star::accessibility;
85 using ::std::for_each;
87 //===== internal ========================================================
89 struct ScAccessibleShapeData
91 ScAccessibleShapeData() : pAccShape(NULL), pRelationCell(NULL), bSelected(sal_False), bSelectable(sal_True) {}
92 ~ScAccessibleShapeData();
93 mutable ::accessibility::AccessibleShape* pAccShape;
94 mutable ScAddress* pRelationCell; // if it is NULL this shape is anchored on the table
95 // SdrObject* pShape;
96 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
97 mutable sal_Bool bSelected;
98 sal_Bool bSelectable;
101 ScAccessibleShapeData::~ScAccessibleShapeData()
103 if (pAccShape)
105 pAccShape->dispose();
106 pAccShape->release();
110 struct ScShapeDataLess
112 rtl::OUString msLayerId;
113 rtl::OUString msZOrder;
114 ScShapeDataLess()
115 : msLayerId(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )),
116 msZOrder(RTL_CONSTASCII_USTRINGPARAM( "ZOrder" ))
119 void ConvertLayerId(sal_Int16& rLayerID) const // changes the number of the LayerId so it the accessibility order
121 switch (rLayerID)
123 case SC_LAYER_FRONT:
124 rLayerID = 1;
125 break;
126 case SC_LAYER_BACK:
127 rLayerID = 0;
128 break;
129 case SC_LAYER_INTERN:
130 rLayerID = 2;
131 break;
132 case SC_LAYER_CONTROLS:
133 rLayerID = 3;
134 break;
137 sal_Bool LessThanSheet(const ScAccessibleShapeData* pData) const
139 sal_Bool bResult(sal_False);
140 uno::Reference< beans::XPropertySet> xProps(pData->xShape, uno::UNO_QUERY);
141 if (xProps.is())
143 uno::Any aPropAny = xProps->getPropertyValue(msLayerId);
144 sal_Int16 nLayerID = 0;
145 if( (aPropAny >>= nLayerID) )
147 if (nLayerID == SC_LAYER_BACK)
148 bResult = sal_True;
151 return bResult;
153 sal_Bool operator()(const ScAccessibleShapeData* pData1, const ScAccessibleShapeData* pData2) const
155 sal_Bool bResult(sal_False);
156 if (pData1 && pData2)
158 uno::Reference< beans::XPropertySet> xProps1(pData1->xShape, uno::UNO_QUERY);
159 uno::Reference< beans::XPropertySet> xProps2(pData2->xShape, uno::UNO_QUERY);
160 if (xProps1.is() && xProps2.is())
162 uno::Any aPropAny1 = xProps1->getPropertyValue(msLayerId);
163 uno::Any aPropAny2 = xProps2->getPropertyValue(msLayerId);
164 sal_Int16 nLayerID1(0);
165 sal_Int16 nLayerID2(0);
166 if( (aPropAny1 >>= nLayerID1) && (aPropAny2 >>= nLayerID2) )
168 if (nLayerID1 == nLayerID2)
170 uno::Any aAny1 = xProps1->getPropertyValue(msZOrder);
171 sal_Int32 nZOrder1 = 0;
172 uno::Any aAny2 = xProps2->getPropertyValue(msZOrder);
173 sal_Int32 nZOrder2 = 0;
174 if ( (aAny1 >>= nZOrder1) && (aAny2 >>= nZOrder2) )
175 bResult = (nZOrder1 < nZOrder2);
177 else
179 ConvertLayerId(nLayerID1);
180 ConvertLayerId(nLayerID2);
181 bResult = (nLayerID1 < nLayerID2);
186 else if (pData1 && !pData2)
187 bResult = LessThanSheet(pData1);
188 else if (!pData1 && pData2)
189 bResult = !LessThanSheet(pData2);
190 else
191 bResult = sal_False;
192 return bResult;
196 struct DeselectShape
198 void operator() (const ScAccessibleShapeData* pAccShapeData) const
200 if (pAccShapeData)
202 pAccShapeData->bSelected = sal_False;
203 if (pAccShapeData->pAccShape)
204 pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED);
209 struct SelectShape
211 uno::Reference < drawing::XShapes > xShapes;
212 SelectShape(uno::Reference<drawing::XShapes>& xTemp) : xShapes(xTemp) {}
213 void operator() (const ScAccessibleShapeData* pAccShapeData) const
215 if (pAccShapeData && pAccShapeData->bSelectable)
217 pAccShapeData->bSelected = sal_True;
218 if (pAccShapeData->pAccShape)
219 pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED);
220 if (xShapes.is())
221 xShapes->add(pAccShapeData->xShape);
226 struct Destroy
228 void operator() (ScAccessibleShapeData* pData)
230 if (pData)
231 DELETEZ(pData);
235 class ScChildrenShapes : public SfxListener,
236 public ::accessibility::IAccessibleParent
238 public:
239 ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
240 ~ScChildrenShapes();
242 ///===== SfxListener =====================================================
244 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
246 ///===== IAccessibleParent ===============================================
248 virtual sal_Bool ReplaceChild (
249 ::accessibility::AccessibleShape* pCurrentChild,
250 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
251 const long _nIndex,
252 const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
253 ) throw (::com::sun::star::uno::RuntimeException);
255 ///===== Internal ========================================================
256 void SetDrawBroadcaster();
258 sal_Int32 GetCount() const;
259 uno::Reference< XAccessible > Get(const ScAccessibleShapeData* pData) const;
260 uno::Reference< XAccessible > Get(sal_Int32 nIndex) const;
261 uno::Reference< XAccessible > GetAt(const awt::Point& rPoint) const;
263 // gets the index of the shape starting on 0 (without the index of the table)
264 // returns the selected shape
265 sal_Bool IsSelected(sal_Int32 nIndex,
266 com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape) const;
268 sal_Bool SelectionChanged();
270 void Select(sal_Int32 nIndex);
271 void DeselectAll(); // deselect also the table
272 void SelectAll();
273 sal_Int32 GetSelectedCount() const;
274 uno::Reference< XAccessible > GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const;
275 void Deselect(sal_Int32 nChildIndex);
277 SdrPage* GetDrawPage() const;
279 utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;
281 void VisAreaChanged() const;
282 private:
283 typedef std::vector<ScAccessibleShapeData*> SortedShapes;
285 mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order
287 mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo;
288 mutable com::sun::star::uno::Reference<com::sun::star::view::XSelectionSupplier> xSelectionSupplier;
289 mutable sal_uInt32 mnSdrObjCount;
290 mutable sal_uInt32 mnShapesSelected;
291 ScTabViewShell* mpViewShell;
292 ScAccessibleDocument* mpAccessibleDocument;
293 ScSplitPos meSplitPos;
295 void FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const;
296 sal_Bool FindSelectedShapesChanges(const com::sun::star::uno::Reference<com::sun::star::drawing::XShapes>& xShapes, sal_Bool bCommitChange) const;
297 void FillSelectionSupplier() const;
299 ScAddress* GetAnchor(const uno::Reference<drawing::XShape>& xShape) const;
300 uno::Reference<XAccessibleRelationSet> GetRelationSet(const ScAccessibleShapeData* pData) const;
301 void CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const;
302 void SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const;
303 void AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const;
304 void RemoveShape(const uno::Reference<drawing::XShape>& xShape) const;
306 sal_Bool FindShape(const uno::Reference<drawing::XShape>& xShape, SortedShapes::iterator& rItr) const;
308 sal_Int8 Compare(const ScAccessibleShapeData* pData1,
309 const ScAccessibleShapeData* pData2) const;
312 ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
314 mnShapesSelected(0),
315 mpViewShell(pViewShell),
316 mpAccessibleDocument(pAccessibleDocument),
317 meSplitPos(eSplitPos)
319 FillSelectionSupplier();
320 maZOrderedShapes.push_back(NULL); // add an element which represents the table
322 GetCount(); // fill list with filtered shapes (no internal shapes)
324 if (mnShapesSelected)
326 //set flag on every selected shape
327 if (!xSelectionSupplier.is())
328 throw uno::RuntimeException();
330 uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
331 if (xShapes.is())
332 FindSelectedShapesChanges(xShapes, sal_False);
334 if (pViewShell)
336 SfxBroadcaster* pDrawBC = pViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
337 if (pDrawBC)
339 StartListening(*pDrawBC);
341 maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
342 maShapeTreeInfo.SetSdrView(pViewShell->GetViewData()->GetScDrawView());
343 maShapeTreeInfo.SetController(NULL);
344 maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos));
345 maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
350 ScChildrenShapes::~ScChildrenShapes()
352 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy());
353 if (mpViewShell)
355 SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
356 if (pDrawBC)
357 EndListening(*pDrawBC);
361 void ScChildrenShapes::SetDrawBroadcaster()
363 if (mpViewShell)
365 SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
366 if (pDrawBC)
368 StartListening(*pDrawBC, TRUE);
370 maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(mpViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
371 maShapeTreeInfo.SetSdrView(mpViewShell->GetViewData()->GetScDrawView());
372 maShapeTreeInfo.SetController(NULL);
373 maShapeTreeInfo.SetWindow(mpViewShell->GetWindowByPos(meSplitPos));
374 maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
379 void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint)
381 if ( rHint.ISA( SdrHint ) )
383 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
384 if (pSdrHint)
386 SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
387 if (pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->GetPage() == GetDrawPage()) &&
388 (pObj->GetPage() == pObj->GetObjList()) ) //#108480# only do something if the object lies direct on the page
390 switch (pSdrHint->GetKind())
392 case HINT_OBJCHG : // Objekt geaendert
394 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
395 if (xShape.is())
397 ScShapeDataLess aLess;
398 std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), aLess); // sort, because the z index or layer could be changed
399 CheckWhetherAnchorChanged(xShape);
402 break;
403 case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
405 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
406 if (xShape.is())
407 AddShape(xShape, sal_True);
409 break;
410 case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
412 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
413 if (xShape.is())
414 RemoveShape(xShape);
416 break;
417 default :
419 // other events are not interesting
421 break;
428 sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurrentChild,
429 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
430 const long _nIndex, const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo)
431 throw (uno::RuntimeException)
433 // create the new child
434 ::accessibility::AccessibleShape* pReplacement = ::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
435 ::accessibility::AccessibleShapeInfo ( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex ),
436 _rShapeTreeInfo
438 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pReplacement ); // keep this alive (do this before calling Init!)
439 if ( pReplacement )
440 pReplacement->Init();
442 sal_Bool bResult(sal_False);
443 if (pCurrentChild && pReplacement)
445 DBG_ASSERT(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted");
446 SortedShapes::iterator aItr;
447 FindShape(pCurrentChild->GetXShape(), aItr);
448 if (aItr != maZOrderedShapes.end() && (*aItr))
450 if ((*aItr)->pAccShape)
452 DBG_ASSERT((*aItr)->pAccShape == pCurrentChild, "wrong child found");
453 AccessibleEventObject aEvent;
454 aEvent.EventId = AccessibleEventId::CHILD;
455 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
456 aEvent.OldValue <<= uno::makeAny(uno::Reference<XAccessible>(pCurrentChild));
458 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
460 pCurrentChild->dispose();
462 (*aItr)->pAccShape = pReplacement;
463 AccessibleEventObject aEvent;
464 aEvent.EventId = AccessibleEventId::CHILD;
465 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
466 aEvent.NewValue <<= uno::makeAny(uno::Reference<XAccessible>(pReplacement));
468 mpAccessibleDocument->CommitChange(aEvent); // child is new - event
469 bResult = sal_True;
472 return bResult;
475 sal_Int32 ScChildrenShapes::GetCount() const
477 SdrPage* pDrawPage = GetDrawPage();
478 if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in
480 mnSdrObjCount = pDrawPage->GetObjCount();
481 maZOrderedShapes.reserve(mnSdrObjCount + 1); // the table is always in
482 for (sal_uInt32 i = 0; i < mnSdrObjCount; ++i)
484 SdrObject* pObj = pDrawPage->GetObj(i);
485 if (pObj/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/)
487 uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY);
488 AddShape(xShape, sal_False); //inserts in the correct order
492 return maZOrderedShapes.size();
495 uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
497 if (!pData)
498 return NULL;
500 if (!pData->pAccShape)
502 ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
503 ::accessibility::AccessibleShapeInfo aShapeInfo(pData->xShape, mpAccessibleDocument, const_cast<ScChildrenShapes*>(this));
504 pData->pAccShape = rShapeHandler.CreateAccessibleObject(
505 aShapeInfo, maShapeTreeInfo);
506 if (pData->pAccShape)
508 pData->pAccShape->acquire();
509 pData->pAccShape->Init();
510 if (pData->bSelected)
511 pData->pAccShape->SetState(AccessibleStateType::SELECTED);
512 if (!pData->bSelectable)
513 pData->pAccShape->ResetState(AccessibleStateType::SELECTABLE);
514 pData->pAccShape->SetRelationSet(GetRelationSet(pData));
517 return pData->pAccShape;
520 uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const
522 if (maZOrderedShapes.size() <= 1)
523 GetCount(); // fill list with filtered shapes (no internal shapes)
525 if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size())
526 return NULL;
528 return Get(maZOrderedShapes[nIndex]);
531 uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint) const
533 uno::Reference<XAccessible> xAccessible;
534 if(mpViewShell)
536 sal_Int32 i(maZOrderedShapes.size() - 1);
537 sal_Bool bFound(sal_False);
538 while (!bFound && i >= 0)
540 ScAccessibleShapeData* pShape = maZOrderedShapes[i];
541 if (pShape)
543 if (!pShape->pAccShape)
544 Get(pShape);
546 if (pShape->pAccShape)
548 Point aPoint(VCLPoint(rPoint));
549 aPoint -= VCLRectangle(pShape->pAccShape->getBounds()).TopLeft();
550 if (pShape->pAccShape->containsPoint(AWTPoint(aPoint)))
552 xAccessible = pShape->pAccShape;
553 bFound = sal_True;
556 else
558 DBG_ERRORFILE("I should have an accessible shape now!");
561 else
562 bFound = sal_True; // this is the sheet and it lies before the rest of the shapes which are background shapes
564 --i;
567 return xAccessible;
570 sal_Bool ScChildrenShapes::IsSelected(sal_Int32 nIndex,
571 uno::Reference<drawing::XShape>& rShape) const
573 sal_Bool bResult (sal_False);
574 if (maZOrderedShapes.size() <= 1)
575 GetCount(); // fill list with filtered shapes (no internal shapes)
577 if (!xSelectionSupplier.is())
578 throw uno::RuntimeException();
580 if (!maZOrderedShapes[nIndex])
581 return sal_False;
583 bResult = maZOrderedShapes[nIndex]->bSelected;
584 rShape = maZOrderedShapes[nIndex]->xShape;
586 #ifndef PRODUCT // test whether it is truly selected by a slower method
587 uno::Reference< drawing::XShape > xReturnShape;
588 sal_Bool bDebugResult(sal_False);
589 uno::Reference<container::XIndexAccess> xIndexAccess;
590 xSelectionSupplier->getSelection() >>= xIndexAccess;
592 if (xIndexAccess.is())
594 sal_Int32 nCount(xIndexAccess->getCount());
595 if (nCount)
597 uno::Reference< drawing::XShape > xShape;
598 uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape;
599 sal_Int32 i(0);
600 while (!bDebugResult && (i < nCount))
602 xIndexAccess->getByIndex(i) >>= xShape;
603 if (xShape.is() && (xIndexShape.get() == xShape.get()))
605 bDebugResult = sal_True;
606 xReturnShape = xShape;
608 else
609 ++i;
613 DBG_ASSERT((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result");
614 #endif
616 return bResult;
619 sal_Bool ScChildrenShapes::SelectionChanged()
621 sal_Bool bResult(sal_False);
622 if (!xSelectionSupplier.is())
623 throw uno::RuntimeException();
625 uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
627 bResult = FindSelectedShapesChanges(xShapes, sal_True);
629 return bResult;
632 void ScChildrenShapes::Select(sal_Int32 nIndex)
634 if (maZOrderedShapes.size() <= 1)
635 GetCount(); // fill list with filtered shapes (no internal shapes)
637 if (!xSelectionSupplier.is())
638 throw uno::RuntimeException();
640 if (!maZOrderedShapes[nIndex])
641 return;
643 uno::Reference<drawing::XShape> xShape;
644 if (!IsSelected(nIndex, xShape) && maZOrderedShapes[nIndex]->bSelectable)
646 uno::Reference<drawing::XShapes> xShapes;
647 xSelectionSupplier->getSelection() >>= xShapes;
649 if (!xShapes.is())
650 xShapes = new SvxShapeCollection();
652 xShapes->add(maZOrderedShapes[nIndex]->xShape);
656 xSelectionSupplier->select(uno::makeAny(xShapes));
657 maZOrderedShapes[nIndex]->bSelected = sal_True;
658 if (maZOrderedShapes[nIndex]->pAccShape)
659 maZOrderedShapes[nIndex]->pAccShape->SetState(AccessibleStateType::SELECTED);
661 catch (lang::IllegalArgumentException&)
667 void ScChildrenShapes::DeselectAll()
669 if (!xSelectionSupplier.is())
670 throw uno::RuntimeException();
672 sal_Bool bSomethingSelected(sal_True);
675 xSelectionSupplier->select(uno::Any()); //deselects all
677 catch (lang::IllegalArgumentException&)
679 DBG_ERRORFILE("nothing selected before");
680 bSomethingSelected = sal_False;
683 if (bSomethingSelected)
684 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), DeselectShape());
687 void ScChildrenShapes::SelectAll()
689 if (!xSelectionSupplier.is())
690 throw uno::RuntimeException();
692 if (maZOrderedShapes.size() <= 1)
693 GetCount(); // fill list with filtered shapes (no internal shapes)
695 if (maZOrderedShapes.size() > 1)
697 uno::Reference<drawing::XShapes> xShapes;
698 xShapes = new SvxShapeCollection();
702 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), SelectShape(xShapes));
703 xSelectionSupplier->select(uno::makeAny(xShapes));
705 catch (lang::IllegalArgumentException&)
707 SelectionChanged(); // find all selected shapes and set the flags
712 void ScChildrenShapes::FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const
714 uno::Reference<container::XIndexAccess> xIndexAccess;
715 xSelectionSupplier->getSelection() >>= xIndexAccess;
717 if (xIndexAccess.is())
719 sal_uInt32 nCount(xIndexAccess->getCount());
720 for (sal_uInt32 i = 0; i < nCount; ++i)
722 uno::Reference<drawing::XShape> xShape;
723 xIndexAccess->getByIndex(i) >>= xShape;
724 if (xShape.is())
725 rShapes.push_back(xShape);
730 sal_Int32 ScChildrenShapes::GetSelectedCount() const
732 if (!xSelectionSupplier.is())
733 throw uno::RuntimeException();
735 std::vector < uno::Reference < drawing::XShape > > aShapes;
736 FillShapes(aShapes);
738 return aShapes.size();
741 uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const
743 uno::Reference< XAccessible > xAccessible;
745 if (maZOrderedShapes.size() <= 1)
746 GetCount(); // fill list with shapes
748 if (!bTabSelected)
750 std::vector < uno::Reference < drawing::XShape > > aShapes;
751 FillShapes(aShapes);
753 SortedShapes::iterator aItr;
754 if (FindShape(aShapes[nSelectedChildIndex], aItr))
755 xAccessible = Get(aItr - maZOrderedShapes.begin());
757 else
759 SortedShapes::iterator aItr = maZOrderedShapes.begin();
760 SortedShapes::iterator aEndItr = maZOrderedShapes.end();
761 sal_Bool bFound(sal_False);
762 while(!bFound && aItr != aEndItr)
764 if (*aItr)
766 if ((*aItr)->bSelected)
768 if (nSelectedChildIndex == 0)
769 bFound = sal_True;
770 else
771 --nSelectedChildIndex;
774 else
776 if (nSelectedChildIndex == 0)
777 bFound = sal_True;
778 else
779 --nSelectedChildIndex;
781 if (!bFound)
782 ++aItr;
784 if (bFound && *aItr)
785 xAccessible = (*aItr)->pAccShape;
788 return xAccessible;
791 void ScChildrenShapes::Deselect(sal_Int32 nChildIndex)
793 uno::Reference<drawing::XShape> xShape;
794 if (IsSelected(nChildIndex, xShape)) // returns false if it is the sheet
796 if (xShape.is())
798 uno::Reference<drawing::XShapes> xShapes;
799 xSelectionSupplier->getSelection() >>= xShapes;
800 if (xShapes.is())
801 xShapes->remove(xShape);
805 xSelectionSupplier->select(uno::makeAny(xShapes));
807 catch (lang::IllegalArgumentException&)
809 DBG_ERRORFILE("something not selectable");
812 maZOrderedShapes[nChildIndex]->bSelected = sal_False;
813 if (maZOrderedShapes[nChildIndex]->pAccShape)
814 maZOrderedShapes[nChildIndex]->pAccShape->ResetState(AccessibleStateType::SELECTED);
820 SdrPage* ScChildrenShapes::GetDrawPage() const
822 SCTAB nTab(mpAccessibleDocument->getVisibleTable());
823 SdrPage* pDrawPage = NULL;
824 if (mpViewShell)
826 ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
827 if (pDoc && pDoc->GetDrawLayer())
829 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
830 if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
831 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
834 return pDrawPage;
837 struct SetRelation
839 const ScChildrenShapes* mpChildrenShapes;
840 mutable utl::AccessibleRelationSetHelper* mpRelationSet;
841 const ScAddress* mpAddress;
842 SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress)
844 mpChildrenShapes(pChildrenShapes),
845 mpRelationSet(NULL),
846 mpAddress(pAddress)
849 void operator() (const ScAccessibleShapeData* pAccShapeData) const
851 if (pAccShapeData &&
852 ((!pAccShapeData->pRelationCell && !mpAddress) ||
853 (pAccShapeData->pRelationCell && mpAddress && (*(pAccShapeData->pRelationCell) == *mpAddress))))
855 if (!mpRelationSet)
856 mpRelationSet = new utl::AccessibleRelationSetHelper();
858 AccessibleRelation aRelation;
859 aRelation.TargetSet.realloc(1);
860 aRelation.TargetSet[0] = mpChildrenShapes->Get(pAccShapeData);
861 aRelation.RelationType = AccessibleRelationType::CONTROLLER_FOR;
863 mpRelationSet->AddRelation(aRelation);
868 utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const
870 SetRelation aSetRelation(this, pAddress);
871 ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation);
872 return aSetRelation.mpRelationSet;
875 sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, sal_Bool /* bCommitChange */) const
877 sal_Bool bResult(sal_False);
878 SortedShapes aShapesList;
879 uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY);
880 if (xIndexAcc.is())
882 mnShapesSelected = xIndexAcc->getCount();
883 for (sal_uInt32 i = 0; i < mnShapesSelected; ++i)
885 uno::Reference< drawing::XShape > xShape;
886 xIndexAcc->getByIndex(i) >>= xShape;
887 if (xShape.is())
889 ScAccessibleShapeData* pShapeData = new ScAccessibleShapeData();
890 pShapeData->xShape = xShape;
891 aShapesList.push_back(pShapeData);
895 else
896 mnShapesSelected = 0;
897 ScShapeDataLess aLess;
898 std::sort(aShapesList.begin(), aShapesList.end(), aLess);
900 SortedShapes::iterator aXShapesItr(aShapesList.begin());
901 SortedShapes::const_iterator aXShapesEndItr(aShapesList.end());
902 SortedShapes::iterator aDataItr(maZOrderedShapes.begin());
903 SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end());
904 SortedShapes::const_iterator aFocusedItr = aDataEndItr;
905 while((aDataItr != aDataEndItr))
907 if (*aDataItr) // is it realy a shape or only the sheet
909 sal_Int8 nComp(0);
910 if (aXShapesItr == aXShapesEndItr)
911 nComp = -1; // simulate that the Shape is lower, so the selction state will be removed
912 else
913 nComp = Compare(*aDataItr, *aXShapesItr);
914 if (nComp == 0)
916 if (!(*aDataItr)->bSelected)
918 (*aDataItr)->bSelected = sal_True;
919 if ((*aDataItr)->pAccShape)
921 (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED);
922 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
923 bResult = sal_True;
925 aFocusedItr = aDataItr;
927 ++aDataItr;
928 ++aXShapesItr;
930 else if (nComp < 0)
932 if ((*aDataItr)->bSelected)
934 (*aDataItr)->bSelected = sal_False;
935 if ((*aDataItr)->pAccShape)
937 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED);
938 (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
939 bResult = sal_True;
942 ++aDataItr;
944 else
946 DBG_ERRORFILE("here is a selected shape which is not in the childlist");
947 ++aXShapesItr;
948 --mnShapesSelected;
951 else
952 ++aDataItr;
954 if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1))
955 (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED);
957 std::for_each(aShapesList.begin(), aShapesList.end(), Destroy());
959 return bResult;
962 void ScChildrenShapes::FillSelectionSupplier() const
964 if (!xSelectionSupplier.is() && mpViewShell)
966 SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame();
967 if (pViewFrame)
969 SfxFrame* pFrame = pViewFrame->GetFrame();
970 if (pFrame)
972 xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pFrame->GetController(), uno::UNO_QUERY);
973 if (xSelectionSupplier.is())
975 if (mpAccessibleDocument)
976 xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument);
977 uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY);
978 if (xShapes.is())
979 mnShapesSelected = xShapes->getCount();
986 ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const
988 ScAddress* pAddress = NULL;
989 if (mpViewShell)
991 SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
992 uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY);
993 if (pShapeImp && xShapeProp.is())
995 SdrObject *pSdrObj = pShapeImp->GetSdrObject();
996 if (pSdrObj)
998 if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
1000 ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
1001 if (pDoc)
1003 rtl::OUString sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape"));
1004 awt::Point aPoint(xShape->getPosition());
1005 awt::Size aSize(xShape->getSize());
1006 rtl::OUString sType(xShape->getShapeType());
1007 Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
1008 if ( sType.equals(sCaptionShape) )
1010 awt::Point aRelativeCaptionPoint;
1011 rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
1012 xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
1013 Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
1014 Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
1015 aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
1016 aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
1018 ScRange aRange = pDoc->GetRange(mpAccessibleDocument->getVisibleTable(), aRectangle);
1019 pAddress = new ScAddress(aRange.aStart);
1022 // else
1023 // do nothing, because it is always a NULL Pointer
1028 return pAddress;
1031 uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const
1033 utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper();
1035 if(pData && pRelationSet && mpAccessibleDocument)
1037 uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table
1038 if (pData->pRelationCell && xAccessible.is())
1040 uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY);
1041 if (xAccTable.is())
1042 xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col());
1044 AccessibleRelation aRelation;
1045 aRelation.TargetSet.realloc(1);
1046 aRelation.TargetSet[0] = xAccessible;
1047 aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY;
1048 pRelationSet->AddRelation(aRelation);
1051 return pRelationSet;
1054 void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const
1056 SortedShapes::iterator aItr;
1057 if (FindShape(xShape, aItr))
1058 SetAnchor(xShape, *aItr);
1061 void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const
1063 if (pData)
1065 ScAddress* pAddress = GetAnchor(xShape);
1066 if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) ||
1067 (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell))
1069 if (pData->pRelationCell)
1070 delete pData->pRelationCell;
1071 pData->pRelationCell = pAddress;
1072 if (pData->pAccShape)
1073 pData->pAccShape->SetRelationSet(GetRelationSet(pData));
1078 void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const
1080 SortedShapes::iterator aFindItr;
1081 if (!FindShape(xShape, aFindItr))
1083 ScAccessibleShapeData* pShape = new ScAccessibleShapeData();
1084 pShape->xShape = xShape;
1085 SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape);
1086 SetAnchor(xShape, pShape);
1088 uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY);
1089 if (xShapeProp.is())
1091 uno::Any aPropAny = xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )));
1092 sal_Int16 nLayerID = 0;
1093 if( aPropAny >>= nLayerID )
1095 if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
1096 pShape->bSelectable = sal_False;
1097 else
1098 pShape->bSelectable = sal_True;
1103 if (!xSelectionSupplier.is())
1104 throw uno::RuntimeException();
1106 uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
1107 if (xEnumAcc.is())
1109 uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration();
1110 if (xEnum.is())
1112 uno::Reference<drawing::XShape> xSelectedShape;
1113 sal_Bool bFound(sal_False);
1114 while (!bFound && xEnum->hasMoreElements())
1116 xEnum->nextElement() >>= xSelectedShape;
1117 if (xShape.is() && (xShape.get() == xSelectedShape.get()))
1119 pShape->bSelected = sal_True;
1120 bFound = sal_True;
1125 if (mpAccessibleDocument && bCommitChange)
1127 AccessibleEventObject aEvent;
1128 aEvent.EventId = AccessibleEventId::CHILD;
1129 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
1130 aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin());
1132 mpAccessibleDocument->CommitChange(aEvent); // new child - event
1135 else
1137 DBG_ERRORFILE("shape is always in the list");
1141 void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const
1143 SortedShapes::iterator aItr;
1144 if (FindShape(xShape, aItr))
1146 if (mpAccessibleDocument)
1148 uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin()));
1150 delete *aItr;
1151 maZOrderedShapes.erase(aItr);
1153 AccessibleEventObject aEvent;
1154 aEvent.EventId = AccessibleEventId::CHILD;
1155 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
1156 aEvent.OldValue <<= uno::makeAny(xOldAccessible);
1158 mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
1160 else
1162 delete *aItr;
1163 maZOrderedShapes.erase(aItr);
1166 else
1168 DBG_ERRORFILE("shape was not in internal list");
1172 sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const
1174 sal_Bool bResult(sal_False);
1175 ScAccessibleShapeData aShape;
1176 aShape.xShape = xShape;
1177 ScShapeDataLess aLess;
1178 rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess);
1179 if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get()))
1180 bResult = sal_True; // if the shape is found
1182 #ifndef PRODUCT // test whether it finds truly the correct shape (perhaps it is not really sorted)
1183 SortedShapes::iterator aDebugItr = maZOrderedShapes.begin();
1184 SortedShapes::iterator aEndItr = maZOrderedShapes.end();
1185 sal_Bool bFound(sal_False);
1186 while (!bFound && aDebugItr != aEndItr)
1188 if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get()))
1189 bFound = sal_True;
1190 else
1191 ++aDebugItr;
1193 sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end());
1194 DBG_ASSERT((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found");
1195 #endif
1196 return bResult;
1199 sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1,
1200 const ScAccessibleShapeData* pData2) const
1202 ScShapeDataLess aLess;
1204 sal_Bool bResult1(aLess(pData1, pData2));
1205 sal_Bool bResult2(aLess(pData2, pData1));
1207 sal_Int8 nResult(0);
1208 if (!bResult1 && bResult2)
1209 nResult = 1;
1210 else if (bResult1 && !bResult2)
1211 nResult = -1;
1213 return nResult;
1216 struct ScVisAreaChanged
1218 ScAccessibleDocument* mpAccDoc;
1219 ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {}
1220 void operator() (const ScAccessibleShapeData* pAccShapeData) const
1222 if (pAccShapeData && pAccShapeData->pAccShape)
1224 pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc);
1229 void ScChildrenShapes::VisAreaChanged() const
1231 ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument);
1232 std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged);
1235 // ============================================================================
1237 ScAccessibleDocument::ScAccessibleDocument(
1238 const uno::Reference<XAccessible>& rxParent,
1239 ScTabViewShell* pViewShell,
1240 ScSplitPos eSplitPos)
1241 : ScAccessibleDocumentBase(rxParent),
1242 mpViewShell(pViewShell),
1243 meSplitPos(eSplitPos),
1244 mpAccessibleSpreadsheet(NULL),
1245 mpChildrenShapes(NULL),
1246 mpTempAccEdit(NULL),
1247 mbCompleteSheetSelected(sal_False)
1249 if (pViewShell)
1251 pViewShell->AddAccessibilityObject(*this);
1252 Window *pWin = pViewShell->GetWindowByPos(eSplitPos);
1253 if( pWin )
1255 pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1256 USHORT nCount = pWin->GetChildCount();
1257 for( sal_uInt16 i=0; i < nCount; ++i )
1259 Window *pChildWin = pWin->GetChild( i );
1260 if( pChildWin &&
1261 AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1262 AddChild( pChildWin->GetAccessible(), sal_False );
1265 if (pViewShell->GetViewData()->HasEditView( eSplitPos ))
1267 uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewShell->GetViewData()->GetEditView(eSplitPos),
1268 pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(),
1269 CellInEditMode);
1270 AddChild(xAcc, sal_False);
1273 maVisArea = GetVisibleArea_Impl();
1276 void ScAccessibleDocument::Init()
1278 if(!mpChildrenShapes)
1279 mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos);
1282 ScAccessibleDocument::~ScAccessibleDocument(void)
1284 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
1286 // increment refcount to prevent double call off dtor
1287 osl_incrementInterlockedCount( &m_refCount );
1288 dispose();
1292 void SAL_CALL ScAccessibleDocument::disposing()
1294 ScUnoGuard aGuard;
1295 FreeAccessibleSpreadsheet();
1296 if (mpViewShell)
1298 Window *pWin = mpViewShell->GetWindowByPos(meSplitPos);
1299 if( pWin )
1300 pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
1302 mpViewShell->RemoveAccessibilityObject(*this);
1303 mpViewShell = NULL;
1305 if (mpChildrenShapes)
1306 DELETEZ(mpChildrenShapes);
1308 ScAccessibleDocumentBase::disposing();
1311 void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ )
1312 throw (uno::RuntimeException)
1314 disposing();
1317 //===== SfxListener =====================================================
1319 IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
1321 DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
1322 if ( pEvent && pEvent->ISA( VclWindowEvent ) )
1324 VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
1325 DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
1326 switch ( pVclEvent->GetId() )
1328 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
1330 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
1331 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1333 AddChild( pChildWin->GetAccessible(), sal_True );
1336 break;
1337 case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children
1339 Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
1340 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
1342 RemoveChild( pChildWin->GetAccessible(), sal_True );
1345 break;
1348 return 0;
1351 void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1353 if (rHint.ISA( ScAccGridWinFocusLostHint ) )
1355 const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint;
1356 if (rRef.GetOldGridWin() == meSplitPos)
1358 if (mxTempAcc.is() && mpTempAccEdit)
1359 mpTempAccEdit->LostFocus();
1360 else if (mpAccessibleSpreadsheet)
1361 mpAccessibleSpreadsheet->LostFocus();
1362 else
1363 CommitFocusLost();
1366 else if (rHint.ISA( ScAccGridWinFocusGotHint ) )
1368 const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint;
1369 if (rRef.GetNewGridWin() == meSplitPos)
1371 if (mxTempAcc.is() && mpTempAccEdit)
1372 mpTempAccEdit->GotFocus();
1373 else if (mpAccessibleSpreadsheet)
1374 mpAccessibleSpreadsheet->GotFocus();
1375 else
1376 CommitFocusGained();
1379 else if (rHint.ISA( SfxSimpleHint ))
1381 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
1382 // only notify if child exist, otherwise it is not necessary
1383 if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
1384 mpAccessibleSpreadsheet)
1386 FreeAccessibleSpreadsheet();
1387 if (mpChildrenShapes)
1388 DELETEZ(mpChildrenShapes);
1390 // #124567# Accessibility: Shapes / form controls after reload not accessible
1391 if ( !mpChildrenShapes )
1393 mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos );
1396 AccessibleEventObject aEvent;
1397 aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN;
1398 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1399 CommitChange(aEvent); // all childs changed
1401 else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
1403 if (mpChildrenShapes)
1404 mpChildrenShapes->SetDrawBroadcaster();
1406 else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell
1408 if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos))
1410 mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos),
1411 mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(),
1412 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), CellInEditMode);
1413 uno::Reference<XAccessible> xAcc = mpTempAccEdit;
1415 AddChild(xAcc, sal_True);
1417 if (mpAccessibleSpreadsheet)
1418 mpAccessibleSpreadsheet->LostFocus();
1419 else
1420 CommitFocusLost();
1422 mpTempAccEdit->GotFocus();
1425 else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE)
1427 if (mxTempAcc.is())
1429 if (mpTempAccEdit)
1430 mpTempAccEdit->LostFocus();
1432 mpTempAccEdit = NULL;
1433 RemoveChild(mxTempAcc, sal_True);
1435 if (mpAccessibleSpreadsheet)
1436 mpAccessibleSpreadsheet->GotFocus();
1437 else
1438 CommitFocusGained();
1441 else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED))
1443 Rectangle aOldVisArea(maVisArea);
1444 maVisArea = GetVisibleArea_Impl();
1446 if (maVisArea != aOldVisArea)
1448 if (maVisArea.GetSize() != aOldVisArea.GetSize())
1450 AccessibleEventObject aEvent;
1451 aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
1452 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1454 CommitChange(aEvent);
1456 if (mpAccessibleSpreadsheet)
1457 mpAccessibleSpreadsheet->BoundingBoxChanged();
1459 else if (mpAccessibleSpreadsheet)
1461 mpAccessibleSpreadsheet->VisAreaChanged();
1463 if (mpChildrenShapes)
1464 mpChildrenShapes->VisAreaChanged();
1469 ScAccessibleDocumentBase::Notify(rBC, rHint);
1472 void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
1473 throw (uno::RuntimeException)
1475 sal_Bool bSelectionChanged(sal_False);
1476 if (mpAccessibleSpreadsheet)
1478 sal_Bool bOldSelected(mbCompleteSheetSelected);
1479 mbCompleteSheetSelected = IsTableSelected();
1480 if (bOldSelected != mbCompleteSheetSelected)
1482 mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
1483 bSelectionChanged = sal_True;
1487 if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
1488 bSelectionChanged = sal_True;
1490 if (bSelectionChanged)
1492 AccessibleEventObject aEvent;
1493 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1494 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1496 CommitChange(aEvent);
1500 //===== XInterface =====================================================
1502 uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
1503 throw (uno::RuntimeException)
1505 uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
1506 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
1509 void SAL_CALL ScAccessibleDocument::acquire()
1510 throw ()
1512 ScAccessibleContextBase::acquire();
1515 void SAL_CALL ScAccessibleDocument::release()
1516 throw ()
1518 ScAccessibleContextBase::release();
1521 //===== XAccessibleComponent ============================================
1523 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint(
1524 const awt::Point& rPoint )
1525 throw (uno::RuntimeException)
1527 uno::Reference<XAccessible> xAccessible = NULL;
1528 if (containsPoint(rPoint))
1530 ScUnoGuard aGuard;
1531 IsObjectValid();
1532 if (mpChildrenShapes)
1533 xAccessible = mpChildrenShapes->GetAt(rPoint);
1534 if(!xAccessible.is())
1536 if (mxTempAcc.is())
1538 uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext());
1539 uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY);
1540 if (xComp.is())
1542 Rectangle aBound(VCLRectangle(xComp->getBounds()));
1543 if (aBound.IsInside(VCLPoint(rPoint)))
1544 xAccessible = mxTempAcc;
1547 if (!xAccessible.is())
1548 xAccessible = GetAccessibleSpreadsheet();
1551 return xAccessible;
1554 void SAL_CALL ScAccessibleDocument::grabFocus( )
1555 throw (uno::RuntimeException)
1557 ScUnoGuard aGuard;
1558 IsObjectValid();
1559 if (getAccessibleParent().is())
1561 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1562 if (xAccessibleComponent.is())
1564 xAccessibleComponent->grabFocus();
1565 // grab only focus if it does not have the focus and it is not hidden
1566 if (mpViewShell && mpViewShell->GetViewData() &&
1567 (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
1568 mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
1570 mpViewShell->ActivatePart(meSplitPos);
1576 //===== XAccessibleContext ==============================================
1578 /// Return the number of currently visible children.
1579 sal_Int32 SAL_CALL
1580 ScAccessibleDocument::getAccessibleChildCount(void)
1581 throw (uno::RuntimeException)
1583 ScUnoGuard aGuard;
1584 IsObjectValid();
1585 sal_Int32 nCount(1);
1586 if (mpChildrenShapes)
1587 nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
1589 if (mxTempAcc.is())
1590 ++nCount;
1592 return nCount;
1595 /// Return the specified child or NULL if index is invalid.
1596 uno::Reference<XAccessible> SAL_CALL
1597 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex)
1598 throw (uno::RuntimeException,
1599 lang::IndexOutOfBoundsException)
1601 ScUnoGuard aGuard;
1602 IsObjectValid();
1603 uno::Reference<XAccessible> xAccessible;
1604 if (nIndex >= 0)
1606 sal_Int32 nCount(1);
1607 if (mpChildrenShapes)
1609 xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
1610 nCount = mpChildrenShapes->GetCount(); //there is always a table
1612 if (!xAccessible.is())
1614 if (nIndex < nCount)
1615 xAccessible = GetAccessibleSpreadsheet();
1616 else if (nIndex == nCount && mxTempAcc.is())
1617 xAccessible = mxTempAcc;
1621 if (!xAccessible.is())
1622 throw lang::IndexOutOfBoundsException();
1624 return xAccessible;
1627 /// Return the set of current states.
1628 uno::Reference<XAccessibleStateSet> SAL_CALL
1629 ScAccessibleDocument::getAccessibleStateSet(void)
1630 throw (uno::RuntimeException)
1632 ScUnoGuard aGuard;
1633 uno::Reference<XAccessibleStateSet> xParentStates;
1634 if (getAccessibleParent().is())
1636 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1637 xParentStates = xParentContext->getAccessibleStateSet();
1639 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1640 if (IsDefunc(xParentStates))
1641 pStateSet->AddState(AccessibleStateType::DEFUNC);
1642 else
1644 if (IsEditable(xParentStates))
1645 pStateSet->AddState(AccessibleStateType::EDITABLE);
1646 pStateSet->AddState(AccessibleStateType::ENABLED);
1647 pStateSet->AddState(AccessibleStateType::OPAQUE);
1648 if (isShowing())
1649 pStateSet->AddState(AccessibleStateType::SHOWING);
1650 if (isVisible())
1651 pStateSet->AddState(AccessibleStateType::VISIBLE);
1653 return pStateSet;
1656 ///===== XAccessibleSelection ===========================================
1658 void SAL_CALL
1659 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
1660 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1662 ScUnoGuard aGuard;
1663 IsObjectValid();
1665 if (mpChildrenShapes)
1667 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1668 if (mxTempAcc.is())
1669 ++nCount;
1670 if (nChildIndex < 0 || nChildIndex >= nCount)
1671 throw lang::IndexOutOfBoundsException();
1673 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1674 if (xAccessible.is())
1676 sal_Bool bWasTableSelected(IsTableSelected());
1678 if (mpChildrenShapes)
1679 mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1681 if (bWasTableSelected)
1682 mpViewShell->SelectAll();
1684 else
1686 if (mpViewShell)
1687 mpViewShell->SelectAll();
1692 sal_Bool SAL_CALL
1693 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
1694 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1696 ScUnoGuard aGuard;
1697 IsObjectValid();
1698 sal_Bool bResult(sal_False);
1700 if (mpChildrenShapes)
1702 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1703 if (mxTempAcc.is())
1704 ++nCount;
1705 if (nChildIndex < 0 || nChildIndex >= nCount)
1706 throw lang::IndexOutOfBoundsException();
1708 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1709 if (xAccessible.is())
1711 uno::Reference<drawing::XShape> xShape;
1712 bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high
1714 else
1716 if (mxTempAcc.is() && nChildIndex == nCount)
1717 bResult = sal_True;
1718 else
1719 bResult = IsTableSelected();
1722 return bResult;
1725 void SAL_CALL
1726 ScAccessibleDocument::clearAccessibleSelection( )
1727 throw (uno::RuntimeException)
1729 ScUnoGuard aGuard;
1730 IsObjectValid();
1732 if (mpChildrenShapes)
1733 mpChildrenShapes->DeselectAll(); //deselects all (also the table)
1736 void SAL_CALL
1737 ScAccessibleDocument::selectAllAccessibleChildren( )
1738 throw (uno::RuntimeException)
1740 ScUnoGuard aGuard;
1741 IsObjectValid();
1743 if (mpChildrenShapes)
1744 mpChildrenShapes->SelectAll();
1746 // select table after shapes, because while selecting shapes the table will be deselected
1747 if (mpViewShell)
1749 mpViewShell->SelectAll();
1753 sal_Int32 SAL_CALL
1754 ScAccessibleDocument::getSelectedAccessibleChildCount( )
1755 throw (uno::RuntimeException)
1757 ScUnoGuard aGuard;
1758 IsObjectValid();
1759 sal_Int32 nCount(0);
1761 if (mpChildrenShapes)
1762 nCount = mpChildrenShapes->GetSelectedCount();
1764 if (IsTableSelected())
1765 ++nCount;
1767 if (mxTempAcc.is())
1768 ++nCount;
1770 return nCount;
1773 uno::Reference<XAccessible > SAL_CALL
1774 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1775 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1777 ScUnoGuard aGuard;
1778 IsObjectValid();
1779 uno::Reference<XAccessible> xAccessible;
1780 if (mpChildrenShapes)
1782 sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
1783 if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
1784 throw lang::IndexOutOfBoundsException();
1786 sal_Bool bTabMarked(IsTableSelected());
1788 if (mpChildrenShapes)
1789 xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
1790 if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
1791 xAccessible = mxTempAcc;
1792 else if (bTabMarked)
1793 xAccessible = GetAccessibleSpreadsheet();
1796 DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed");
1798 return xAccessible;
1801 void SAL_CALL
1802 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
1803 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1805 ScUnoGuard aGuard;
1806 IsObjectValid();
1808 if (mpChildrenShapes)
1810 sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
1811 if (mxTempAcc.is())
1812 ++nCount;
1813 if (nChildIndex < 0 || nChildIndex >= nCount)
1814 throw lang::IndexOutOfBoundsException();
1816 sal_Bool bTabMarked(IsTableSelected());
1818 uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
1819 if (xAccessible.is())
1821 if (mpChildrenShapes)
1822 mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
1824 if (bTabMarked)
1825 mpViewShell->SelectAll(); // select the table again
1827 else if (bTabMarked)
1828 mpViewShell->Unmark();
1832 //===== XServiceInfo ====================================================
1834 ::rtl::OUString SAL_CALL
1835 ScAccessibleDocument::getImplementationName(void)
1836 throw (uno::RuntimeException)
1838 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
1841 uno::Sequence< ::rtl::OUString> SAL_CALL
1842 ScAccessibleDocument::getSupportedServiceNames(void)
1843 throw (uno::RuntimeException)
1845 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
1846 sal_Int32 nOldSize(aSequence.getLength());
1847 aSequence.realloc(nOldSize + 1);
1848 ::rtl::OUString* pNames = aSequence.getArray();
1850 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView"));
1852 return aSequence;
1855 //===== XTypeProvider =======================================================
1857 uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
1858 throw (uno::RuntimeException)
1860 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
1863 uno::Sequence<sal_Int8> SAL_CALL
1864 ScAccessibleDocument::getImplementationId(void)
1865 throw (uno::RuntimeException)
1867 ScUnoGuard aGuard;
1868 IsObjectValid();
1869 static uno::Sequence<sal_Int8> aId;
1870 if (aId.getLength() == 0)
1872 aId.realloc (16);
1873 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
1875 return aId;
1878 ///===== IAccessibleViewForwarder ========================================
1880 sal_Bool ScAccessibleDocument::IsValid (void) const
1882 ScUnoGuard aGuard;
1883 IsObjectValid();
1884 return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
1887 Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
1889 Rectangle aVisRect(GetBoundingBox());
1891 Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point
1892 aPoint.setX(-aPoint.getX());
1893 aPoint.setY(-aPoint.getY());
1894 aVisRect.SetPos(aPoint);
1896 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1897 if (pWin)
1898 aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
1900 return aVisRect;
1903 Rectangle ScAccessibleDocument::GetVisibleArea() const
1905 ScUnoGuard aGuard;
1906 IsObjectValid();
1907 return maVisArea;
1910 Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
1912 ScUnoGuard aGuard;
1913 IsObjectValid();
1914 Point aPoint;
1915 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1916 if (pWin)
1918 aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
1919 aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
1921 return aPoint;
1924 Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
1926 ScUnoGuard aGuard;
1927 IsObjectValid();
1928 Size aSize;
1929 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1930 if (pWin)
1931 aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
1932 return aSize;
1935 Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
1937 ScUnoGuard aGuard;
1938 IsObjectValid();
1939 Point aPoint;
1940 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1941 if (pWin)
1943 aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
1944 aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
1946 return aPoint;
1949 Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
1951 ScUnoGuard aGuard;
1952 IsObjectValid();
1953 Size aSize;
1954 ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
1955 if (pWin)
1956 aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
1957 return aSize;
1960 //===== internal ========================================================
1962 utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
1964 utl::AccessibleRelationSetHelper* pRelationSet = NULL;
1965 if (mpChildrenShapes)
1966 pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
1967 return pRelationSet;
1970 ::rtl::OUString SAL_CALL
1971 ScAccessibleDocument::createAccessibleDescription(void)
1972 throw (uno::RuntimeException)
1974 rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR));
1975 return sDescription;
1978 ::rtl::OUString SAL_CALL
1979 ScAccessibleDocument::createAccessibleName(void)
1980 throw (uno::RuntimeException)
1982 ScUnoGuard aGuard;
1983 IsObjectValid();
1984 rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME));
1985 sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
1986 sName += rtl::OUString::valueOf(nNumber);
1987 return sName;
1990 Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
1991 throw (uno::RuntimeException)
1993 Rectangle aRect;
1994 if (mpViewShell)
1996 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
1997 if (pWindow)
1998 aRect = pWindow->GetWindowExtentsRelative(NULL);
2000 return aRect;
2003 Rectangle ScAccessibleDocument::GetBoundingBox() const
2004 throw (uno::RuntimeException)
2006 Rectangle aRect;
2007 if (mpViewShell)
2009 Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
2010 if (pWindow)
2011 aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
2013 return aRect;
2016 SCTAB ScAccessibleDocument::getVisibleTable() const
2018 SCTAB nVisibleTable(0);
2019 if (mpViewShell && mpViewShell->GetViewData())
2020 nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
2021 return nVisibleTable;
2024 uno::Reference < XAccessible >
2025 ScAccessibleDocument::GetAccessibleSpreadsheet()
2027 if (!mpAccessibleSpreadsheet && mpViewShell)
2029 mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
2030 mpAccessibleSpreadsheet->acquire();
2031 mpAccessibleSpreadsheet->Init();
2032 mbCompleteSheetSelected = IsTableSelected();
2034 return mpAccessibleSpreadsheet;
2037 void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2039 if (mpAccessibleSpreadsheet)
2041 mpAccessibleSpreadsheet->dispose();
2042 mpAccessibleSpreadsheet->release();
2043 mpAccessibleSpreadsheet = NULL;
2047 sal_Bool ScAccessibleDocument::IsTableSelected() const
2049 sal_Bool bResult (sal_False);
2050 if(mpViewShell)
2052 SCTAB nTab(getVisibleTable());
2053 //#103800#; use a copy of MarkData
2054 ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
2055 aMarkData.MarkToMulti();
2056 if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
2057 bResult = sal_True;
2059 return bResult;
2062 sal_Bool ScAccessibleDocument::IsDefunc(
2063 const uno::Reference<XAccessibleStateSet>& rxParentStates)
2065 return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
2066 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
2069 sal_Bool ScAccessibleDocument::IsEditable(
2070 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
2072 // what is with document protection or readonly documents?
2073 return sal_True;
2076 void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2078 DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before");
2079 if (xAcc.is())
2081 mxTempAcc = xAcc;
2082 if( bFireEvent )
2084 AccessibleEventObject aEvent;
2085 aEvent.Source = uno::Reference<XAccessibleContext>(this);
2086 aEvent.EventId = AccessibleEventId::CHILD;
2087 aEvent.NewValue <<= mxTempAcc;
2088 CommitChange( aEvent );
2093 void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
2095 DBG_ASSERT(mxTempAcc.is(), "this object should be added before");
2096 if (xAcc.is())
2098 DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
2099 if( bFireEvent )
2101 AccessibleEventObject aEvent;
2102 aEvent.Source = uno::Reference<XAccessibleContext>(this);
2103 aEvent.EventId = AccessibleEventId::CHILD;
2104 aEvent.OldValue <<= mxTempAcc;
2105 CommitChange( aEvent );
2107 mxTempAcc = NULL;
2111 rtl::OUString ScAccessibleDocument::GetCurrentCellName() const
2113 String sName( ScResId(STR_ACC_CELL_NAME) );
2114 if (mpViewShell)
2116 String sAddress;
2117 // Document not needed, because only the cell address, but not the tablename is needed
2118 mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL );
2119 sName.SearchAndReplaceAscii("%1", sAddress);
2121 return rtl::OUString(sName);
2124 rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const
2126 return rtl::OUString();