1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include <AccessibleDocument.hxx>
21 #include <AccessibleSpreadsheet.hxx>
22 #include <tabvwsh.hxx>
23 #include <AccessibilityHints.hxx>
24 #include <document.hxx>
25 #include <drwlayer.hxx>
26 #include <DrawModelBroadcaster.hxx>
27 #include <drawview.hxx>
28 #include <gridwin.hxx>
29 #include <AccessibleEditObject.hxx>
30 #include <userdat.hxx>
31 #include <scresid.hxx>
32 #include <strings.hrc>
33 #include <strings.hxx>
34 #include <markdata.hxx>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
39 #include <com/sun/star/accessibility/AccessibleRole.hpp>
40 #include <com/sun/star/view/XSelectionSupplier.hpp>
41 #include <com/sun/star/drawing/ShapeCollection.hpp>
42 #include <com/sun/star/drawing/XShape.hpp>
43 #include <com/sun/star/drawing/XShapes.hpp>
44 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
45 #include <o3tl/safeint.hxx>
46 #include <unotools/accessiblestatesethelper.hxx>
47 #include <tools/gen.hxx>
48 #include <svx/svdpage.hxx>
49 #include <svx/svdobj.hxx>
50 #include <svx/ShapeTypeHandler.hxx>
51 #include <svx/AccessibleShape.hxx>
52 #include <svx/AccessibleShapeTreeInfo.hxx>
53 #include <svx/AccessibleShapeInfo.hxx>
54 #include <svx/IAccessibleParent.hxx>
55 #include <comphelper/sequence.hxx>
56 #include <sfx2/viewfrm.hxx>
57 #include <sfx2/docfile.hxx>
58 #include <svx/unoshape.hxx>
59 #include <unotools/accessiblerelationsethelper.hxx>
60 #include <toolkit/helper/convert.hxx>
61 #include <vcl/svapp.hxx>
63 #include <svx/AccessibleControlShape.hxx>
64 #include <svx/SvxShapeTypes.hxx>
65 #include <sfx2/objsh.hxx>
66 #include <editeng/editview.hxx>
67 #include <editeng/editeng.hxx>
68 #include <comphelper/processfactory.hxx>
72 #include <svx/unoapi.hxx>
83 using namespace ::com::sun::star
;
84 using namespace ::com::sun::star::accessibility
;
86 //===== internal ========================================================
90 struct ScAccessibleShapeData
92 ScAccessibleShapeData(css::uno::Reference
< css::drawing::XShape
> xShape_
);
93 ~ScAccessibleShapeData();
94 mutable rtl::Reference
< ::accessibility::AccessibleShape
> pAccShape
;
95 mutable std::optional
<ScAddress
> xRelationCell
; // if it is NULL this shape is anchored on the table
96 css::uno::Reference
< css::drawing::XShape
> xShape
;
97 mutable bool bSelected
;
99 // cache these to make the sorting cheaper
100 std::optional
<sal_Int16
> mxLayerID
;
101 std::optional
<sal_Int32
> mxZOrder
;
106 ScAccessibleShapeData::ScAccessibleShapeData(css::uno::Reference
< css::drawing::XShape
> xShape_
)
108 bSelected(false), bSelectable(true)
110 static constexpr OUStringLiteral gsLayerId
= u
"LayerID";
111 static constexpr OUStringLiteral gsZOrder
= u
"ZOrder";
112 uno::Reference
< beans::XPropertySet
> xProps(xShape
, uno::UNO_QUERY
);
115 uno::Any aAny
= xProps
->getPropertyValue(gsLayerId
);
117 if (aAny
>>= nLayerID
)
118 mxLayerID
= nLayerID
;
120 aAny
= xProps
->getPropertyValue(gsZOrder
);
121 if (aAny
>>= nZOrder
)
126 ScAccessibleShapeData::~ScAccessibleShapeData()
130 pAccShape
->dispose();
136 struct ScShapeDataLess
138 static void ConvertLayerId(sal_Int16
& rLayerID
) // changes the number of the LayerId so it the accessibility order
140 // note: MSVC 2017 ICE's if this is written as "switch" so use "if"
141 if (sal_uInt8(SC_LAYER_FRONT
) == rLayerID
)
145 else if (sal_uInt8(SC_LAYER_BACK
) == rLayerID
)
149 else if (sal_uInt8(SC_LAYER_INTERN
) == rLayerID
)
153 else if (sal_uInt8(SC_LAYER_CONTROLS
) == rLayerID
)
158 static bool LessThanSheet(const ScAccessibleShapeData
* pData
)
161 if (pData
->mxLayerID
)
163 if (SdrLayerID(*pData
->mxLayerID
) == SC_LAYER_BACK
)
168 bool operator()(const ScAccessibleShapeData
* pData1
, const ScAccessibleShapeData
* pData2
) const
171 if (pData1
&& pData2
)
173 if( pData1
->mxLayerID
&& pData2
->mxLayerID
)
175 sal_Int16 nLayerID1
= *pData1
->mxLayerID
;
176 sal_Int16 nLayerID2
= *pData2
->mxLayerID
;
177 if (nLayerID1
== nLayerID2
)
179 if ( pData1
->mxZOrder
&& pData2
->mxZOrder
)
180 bResult
= (*pData1
->mxZOrder
< *pData2
->mxZOrder
);
184 ConvertLayerId(nLayerID1
);
185 ConvertLayerId(nLayerID2
);
186 bResult
= (nLayerID1
< nLayerID2
);
190 else if (pData1
&& !pData2
)
191 bResult
= LessThanSheet(pData1
);
192 else if (!pData1
&& pData2
)
193 bResult
= !LessThanSheet(pData2
);
202 class ScChildrenShapes
: public SfxListener
,
203 public ::accessibility::IAccessibleParent
206 ScChildrenShapes(ScAccessibleDocument
* pAccessibleDocument
, ScTabViewShell
* pViewShell
, ScSplitPos eSplitPos
);
207 virtual ~ScChildrenShapes() override
;
209 ///===== SfxListener =====================================================
211 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
213 ///===== IAccessibleParent ===============================================
215 virtual bool ReplaceChild (
216 ::accessibility::AccessibleShape
* pCurrentChild
,
217 const css::uno::Reference
< css::drawing::XShape
>& _rxShape
,
218 const tools::Long _nIndex
,
219 const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
222 virtual ::accessibility::AccessibleControlShape
* GetAccControlShapeFromModel
223 (css::beans::XPropertySet
* pSet
) override
;
224 virtual css::uno::Reference
< css::accessibility::XAccessible
>
225 GetAccessibleCaption (const css::uno::Reference
<css::drawing::XShape
>& xShape
) override
;
226 ///===== Internal ========================================================
227 void SetDrawBroadcaster();
229 sal_Int32
GetCount() const;
230 uno::Reference
< XAccessible
> Get(const ScAccessibleShapeData
* pData
) const;
231 uno::Reference
< XAccessible
> Get(sal_Int32 nIndex
) const;
232 uno::Reference
< XAccessible
> GetAt(const awt::Point
& rPoint
) const;
234 // gets the index of the shape starting on 0 (without the index of the table)
235 // returns the selected shape
236 bool IsSelected(sal_Int32 nIndex
,
237 css::uno::Reference
<css::drawing::XShape
>& rShape
) const;
239 bool SelectionChanged();
241 void Select(sal_Int32 nIndex
);
242 void DeselectAll(); // deselect also the table
244 sal_Int32
GetSelectedCount() const;
245 uno::Reference
< XAccessible
> GetSelected(sal_Int32 nSelectedChildIndex
, bool bTabSelected
) const;
246 void Deselect(sal_Int32 nChildIndex
);
248 SdrPage
* GetDrawPage() const;
250 utl::AccessibleRelationSetHelper
* GetRelationSet(const ScAddress
* pAddress
) const;
252 void VisAreaChanged() const;
254 typedef std::vector
<ScAccessibleShapeData
*> SortedShapes
;
255 typedef std::unordered_map
<css::uno::Reference
< css::drawing::XShape
>, ScAccessibleShapeData
*> ShapesMap
;
257 mutable SortedShapes maZOrderedShapes
; // a null pointer represents the sheet in the correct order
258 mutable ShapesMap maShapesMap
;
259 mutable bool mbShapesNeedSorting
; // set if maZOrderedShapes needs sorting
261 mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo
;
262 mutable css::uno::Reference
<css::view::XSelectionSupplier
> xSelectionSupplier
;
263 mutable size_t mnSdrObjCount
;
264 mutable sal_uInt32 mnShapesSelected
;
265 ScTabViewShell
* mpViewShell
;
266 ScAccessibleDocument
* mpAccessibleDocument
;
267 ScSplitPos meSplitPos
;
269 void FillShapes(std::vector
< uno::Reference
< drawing::XShape
> >& rShapes
) const;
270 bool FindSelectedShapesChanges(const css::uno::Reference
<css::drawing::XShapes
>& xShapes
) const;
272 std::optional
<ScAddress
> GetAnchor(const uno::Reference
<drawing::XShape
>& xShape
) const;
273 uno::Reference
<XAccessibleRelationSet
> GetRelationSet(const ScAccessibleShapeData
* pData
) const;
274 void SetAnchor(const uno::Reference
<drawing::XShape
>& xShape
, ScAccessibleShapeData
* pData
) const;
275 void AddShape(const uno::Reference
<drawing::XShape
>& xShape
, bool bCommitChange
) const;
276 void RemoveShape(const uno::Reference
<drawing::XShape
>& xShape
) const;
278 bool FindShape(const uno::Reference
<drawing::XShape
>& xShape
, SortedShapes::iterator
& rItr
) const;
280 static sal_Int8
Compare(const ScAccessibleShapeData
* pData1
,
281 const ScAccessibleShapeData
* pData2
);
284 ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument
* pAccessibleDocument
, ScTabViewShell
* pViewShell
, ScSplitPos eSplitPos
)
286 mbShapesNeedSorting(false),
288 mpViewShell(pViewShell
),
289 mpAccessibleDocument(pAccessibleDocument
),
290 meSplitPos(eSplitPos
)
294 SfxViewFrame
* pViewFrame
= mpViewShell
->GetViewFrame();
297 xSelectionSupplier
= uno::Reference
<view::XSelectionSupplier
>(pViewFrame
->GetFrame().GetController(), uno::UNO_QUERY
);
298 if (xSelectionSupplier
.is())
300 xSelectionSupplier
->addSelectionChangeListener(mpAccessibleDocument
);
301 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
303 mnShapesSelected
= xShapes
->getCount();
308 maZOrderedShapes
.push_back(nullptr); // add an element which represents the table
310 GetCount(); // fill list with filtered shapes (no internal shapes)
312 if (mnShapesSelected
)
314 //set flag on every selected shape
315 if (!xSelectionSupplier
.is())
316 throw uno::RuntimeException();
318 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
320 FindSelectedShapesChanges(xShapes
);
325 ScViewData
& rViewData
= pViewShell
->GetViewData();
326 SfxBroadcaster
* pDrawBC
= rViewData
.GetDocument().GetDrawBroadcaster();
329 StartListening(*pDrawBC
);
331 maShapeTreeInfo
.SetModelBroadcaster( new ScDrawModelBroadcaster(rViewData
.GetDocument().GetDrawLayer()) );
332 maShapeTreeInfo
.SetSdrView(rViewData
.GetScDrawView());
333 maShapeTreeInfo
.SetController(nullptr);
334 maShapeTreeInfo
.SetDevice(pViewShell
->GetWindowByPos(meSplitPos
));
335 maShapeTreeInfo
.SetViewForwarder(mpAccessibleDocument
);
339 ScChildrenShapes::~ScChildrenShapes()
341 for (ScAccessibleShapeData
* pShapeData
: maZOrderedShapes
)
345 SfxBroadcaster
* pDrawBC
= mpViewShell
->GetViewData().GetDocument().GetDrawBroadcaster();
347 EndListening(*pDrawBC
);
349 if (mpAccessibleDocument
&& xSelectionSupplier
.is())
350 xSelectionSupplier
->removeSelectionChangeListener(mpAccessibleDocument
);
353 void ScChildrenShapes::SetDrawBroadcaster()
358 ScViewData
& rViewData
= mpViewShell
->GetViewData();
359 SfxBroadcaster
* pDrawBC
= rViewData
.GetDocument().GetDrawBroadcaster();
362 StartListening(*pDrawBC
, DuplicateHandling::Prevent
);
364 maShapeTreeInfo
.SetModelBroadcaster( new ScDrawModelBroadcaster(rViewData
.GetDocument().GetDrawLayer()) );
365 maShapeTreeInfo
.SetSdrView(rViewData
.GetScDrawView());
366 maShapeTreeInfo
.SetController(nullptr);
367 maShapeTreeInfo
.SetDevice(mpViewShell
->GetWindowByPos(meSplitPos
));
368 maShapeTreeInfo
.SetViewForwarder(mpAccessibleDocument
);
372 void ScChildrenShapes::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
374 if (rHint
.GetId() != SfxHintId::ThisIsAnSdrHint
)
376 const SdrHint
* pSdrHint
= static_cast<const SdrHint
*>(&rHint
);
378 SdrObject
* pObj
= const_cast<SdrObject
*>(pSdrHint
->GetObject());
379 if (!(pObj
&& /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj
->getSdrPageFromSdrObject() == GetDrawPage()) &&
380 (pObj
->getSdrPageFromSdrObject() == pObj
->getParentSdrObjListFromSdrObject())) ) //only do something if the object lies direct on the page
383 switch (pSdrHint
->GetKind())
385 case SdrHintKind::ObjectChange
: // object changed
387 uno::Reference
<drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
390 mbShapesNeedSorting
= true; // sort, because the z index or layer could be changed
391 auto it
= maShapesMap
.find(xShape
);
392 if (it
!= maShapesMap
.end())
393 SetAnchor(xShape
, it
->second
);
397 case SdrHintKind::ObjectInserted
: // new drawing object inserted
399 uno::Reference
<drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
401 AddShape(xShape
, true);
404 case SdrHintKind::ObjectRemoved
: // Removed drawing object from list
406 uno::Reference
<drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
413 // other events are not interesting
419 bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape
* pCurrentChild
,
420 const css::uno::Reference
< css::drawing::XShape
>& _rxShape
,
421 const tools::Long
/*_nIndex*/, const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
)
423 // create the new child
424 rtl::Reference
< ::accessibility::AccessibleShape
> pReplacement(::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
425 ::accessibility::AccessibleShapeInfo ( _rxShape
, pCurrentChild
->getAccessibleParent(), this ),
430 if (pReplacement
.is())
432 OSL_ENSURE(pCurrentChild
->GetXShape().get() == pReplacement
->GetXShape().get(), "XShape changes and should be inserted sorted");
433 auto it
= maShapesMap
.find(pCurrentChild
->GetXShape());
434 if (it
!= maShapesMap
.end() && it
->second
->pAccShape
.is())
436 OSL_ENSURE(it
->second
->pAccShape
== pCurrentChild
, "wrong child found");
437 AccessibleEventObject aEvent
;
438 aEvent
.EventId
= AccessibleEventId::CHILD
;
439 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
440 aEvent
.OldValue
<<= uno::Reference
<XAccessible
>(pCurrentChild
);
442 mpAccessibleDocument
->CommitChange(aEvent
); // child is gone - event
444 pCurrentChild
->dispose();
447 // Init after above possible pCurrentChild->dispose so we don't trigger the assert
448 // ScDrawModelBroadcaster::addShapeEventListener of duplicate listeners
449 pReplacement
->Init();
451 if (it
!= maShapesMap
.end())
453 it
->second
->pAccShape
= pReplacement
;
454 AccessibleEventObject aEvent
;
455 aEvent
.EventId
= AccessibleEventId::CHILD
;
456 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
457 aEvent
.NewValue
<<= uno::Reference
<XAccessible
>(pReplacement
.get());
459 mpAccessibleDocument
->CommitChange(aEvent
); // child is new - event
466 ::accessibility::AccessibleControlShape
* ScChildrenShapes::GetAccControlShapeFromModel(css::beans::XPropertySet
* pSet
)
468 GetCount(); // populate
469 for (ScAccessibleShapeData
* pShape
: maZOrderedShapes
)
473 rtl::Reference
< ::accessibility::AccessibleShape
> pAccShape(pShape
->pAccShape
);
474 if (pAccShape
.is() && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape
->GetXShape()) == ::accessibility::DRAWING_CONTROL
)
476 ::accessibility::AccessibleControlShape
*pCtlAccShape
= static_cast < ::accessibility::AccessibleControlShape
* >(pAccShape
.get());
477 if (pCtlAccShape
&& pCtlAccShape
->GetControlModel() == pSet
)
485 css::uno::Reference
< css::accessibility::XAccessible
>
486 ScChildrenShapes::GetAccessibleCaption (const css::uno::Reference
< css::drawing::XShape
>& xShape
)
488 GetCount(); // populate
489 auto it
= maShapesMap
.find(xShape
);
490 if (it
== maShapesMap
.end())
492 ScAccessibleShapeData
* pShape
= it
->second
;
493 css::uno::Reference
< css::accessibility::XAccessible
> xNewChild( pShape
->pAccShape
.get() );
499 sal_Int32
ScChildrenShapes::GetCount() const
501 SdrPage
* pDrawPage
= GetDrawPage();
502 if (pDrawPage
&& (maZOrderedShapes
.size() == 1)) // the table is always in
504 mnSdrObjCount
= pDrawPage
->GetObjCount();
505 maZOrderedShapes
.reserve(mnSdrObjCount
+ 1); // the table is always in
506 for (size_t i
= 0; i
< mnSdrObjCount
; ++i
)
508 SdrObject
* pObj
= pDrawPage
->GetObj(i
);
509 if (pObj
/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/)
511 uno::Reference
< drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
512 AddShape(xShape
, false); //inserts in the correct order
516 return maZOrderedShapes
.size();
519 uno::Reference
< XAccessible
> ScChildrenShapes::Get(const ScAccessibleShapeData
* pData
) const
524 if (!pData
->pAccShape
.is())
526 ::accessibility::ShapeTypeHandler
& rShapeHandler
= ::accessibility::ShapeTypeHandler::Instance();
527 ::accessibility::AccessibleShapeInfo
aShapeInfo(pData
->xShape
, mpAccessibleDocument
, const_cast<ScChildrenShapes
*>(this));
528 pData
->pAccShape
= rShapeHandler
.CreateAccessibleObject(
529 aShapeInfo
, maShapeTreeInfo
);
530 if (pData
->pAccShape
.is())
532 pData
->pAccShape
->Init();
533 if (pData
->bSelected
)
534 pData
->pAccShape
->SetState(AccessibleStateType::SELECTED
);
535 if (!pData
->bSelectable
)
536 pData
->pAccShape
->ResetState(AccessibleStateType::SELECTABLE
);
537 pData
->pAccShape
->SetRelationSet(GetRelationSet(pData
));
540 return pData
->pAccShape
.get();
543 uno::Reference
< XAccessible
> ScChildrenShapes::Get(sal_Int32 nIndex
) const
545 if (maZOrderedShapes
.size() <= 1)
546 GetCount(); // fill list with filtered shapes (no internal shapes)
548 if (mbShapesNeedSorting
)
550 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
551 mbShapesNeedSorting
= false;
554 if (o3tl::make_unsigned(nIndex
) >= maZOrderedShapes
.size())
557 return Get(maZOrderedShapes
[nIndex
]);
560 uno::Reference
< XAccessible
> ScChildrenShapes::GetAt(const awt::Point
& rPoint
) const
562 uno::Reference
<XAccessible
> xAccessible
;
565 if (mbShapesNeedSorting
)
567 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
568 mbShapesNeedSorting
= false;
571 sal_Int32
i(maZOrderedShapes
.size() - 1);
573 while (!bFound
&& i
>= 0)
575 ScAccessibleShapeData
* pShape
= maZOrderedShapes
[i
];
578 if (!pShape
->pAccShape
.is())
581 if (pShape
->pAccShape
.is())
583 Point
aPoint(VCLPoint(rPoint
));
584 aPoint
-= VCLRectangle(pShape
->pAccShape
->getBounds()).TopLeft();
585 if (pShape
->pAccShape
->containsPoint(AWTPoint(aPoint
)))
587 xAccessible
= pShape
->pAccShape
.get();
593 OSL_FAIL("I should have an accessible shape now!");
597 bFound
= true; // this is the sheet and it lies before the rest of the shapes which are background shapes
605 bool ScChildrenShapes::IsSelected(sal_Int32 nIndex
,
606 uno::Reference
<drawing::XShape
>& rShape
) const
608 bool bResult (false);
609 if (maZOrderedShapes
.size() <= 1)
610 GetCount(); // fill list with filtered shapes (no internal shapes)
612 if (!xSelectionSupplier
.is())
613 throw uno::RuntimeException();
615 if (mbShapesNeedSorting
)
617 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
618 mbShapesNeedSorting
= false;
621 if (!maZOrderedShapes
[nIndex
])
624 bResult
= maZOrderedShapes
[nIndex
]->bSelected
;
625 rShape
= maZOrderedShapes
[nIndex
]->xShape
;
627 #if OSL_DEBUG_LEVEL > 0 // test whether it is truly selected by a slower method
628 uno::Reference
< drawing::XShape
> xReturnShape
;
629 bool bDebugResult(false);
630 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
634 sal_Int32
nCount(xShapes
->getCount());
637 uno::Reference
< drawing::XShape
> xShape
;
638 uno::Reference
< drawing::XShape
> xIndexShape
= maZOrderedShapes
[nIndex
]->xShape
;
640 while (!bDebugResult
&& (i
< nCount
))
642 xShapes
->getByIndex(i
) >>= xShape
;
643 if (xShape
.is() && (xIndexShape
.get() == xShape
.get()))
646 xReturnShape
= xShape
;
653 OSL_ENSURE((bResult
== bDebugResult
) && ((bResult
&& (rShape
.get() == xReturnShape
.get())) || !bResult
), "found the wrong shape or result");
659 bool ScChildrenShapes::SelectionChanged()
662 if (!xSelectionSupplier
.is())
663 throw uno::RuntimeException();
665 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
667 bResult
= FindSelectedShapesChanges(xShapes
);
672 void ScChildrenShapes::Select(sal_Int32 nIndex
)
674 if (maZOrderedShapes
.size() <= 1)
675 GetCount(); // fill list with filtered shapes (no internal shapes)
677 if (!xSelectionSupplier
.is())
678 throw uno::RuntimeException();
680 if (mbShapesNeedSorting
)
682 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
683 mbShapesNeedSorting
= false;
686 if (!maZOrderedShapes
[nIndex
])
689 uno::Reference
<drawing::XShape
> xShape
;
690 if (IsSelected(nIndex
, xShape
) || !maZOrderedShapes
[nIndex
]->bSelectable
)
693 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
696 xShapes
= drawing::ShapeCollection::create(
697 comphelper::getProcessComponentContext());
699 xShapes
->add(maZOrderedShapes
[nIndex
]->xShape
);
703 xSelectionSupplier
->select(uno::makeAny(xShapes
));
704 maZOrderedShapes
[nIndex
]->bSelected
= true;
705 if (maZOrderedShapes
[nIndex
]->pAccShape
.is())
706 maZOrderedShapes
[nIndex
]->pAccShape
->SetState(AccessibleStateType::SELECTED
);
708 catch (lang::IllegalArgumentException
&)
713 void ScChildrenShapes::DeselectAll()
715 if (!xSelectionSupplier
.is())
716 throw uno::RuntimeException();
718 bool bSomethingSelected(true);
721 xSelectionSupplier
->select(uno::Any()); //deselects all
723 catch (lang::IllegalArgumentException
&)
725 OSL_FAIL("nothing selected before");
726 bSomethingSelected
= false;
729 if (bSomethingSelected
)
730 for (const ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
733 pAccShapeData
->bSelected
= false;
734 if (pAccShapeData
->pAccShape
.is())
735 pAccShapeData
->pAccShape
->ResetState(AccessibleStateType::SELECTED
);
740 void ScChildrenShapes::SelectAll()
742 if (!xSelectionSupplier
.is())
743 throw uno::RuntimeException();
745 if (maZOrderedShapes
.size() <= 1)
746 GetCount(); // fill list with filtered shapes (no internal shapes)
748 if (maZOrderedShapes
.size() <= 1)
751 uno::Reference
<drawing::XShapes
> xShapes
= drawing::ShapeCollection::create(
752 comphelper::getProcessComponentContext());
756 for (const ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
758 if (pAccShapeData
&& pAccShapeData
->bSelectable
)
760 pAccShapeData
->bSelected
= true;
761 if (pAccShapeData
->pAccShape
.is())
762 pAccShapeData
->pAccShape
->SetState(AccessibleStateType::SELECTED
);
764 xShapes
->add(pAccShapeData
->xShape
);
767 xSelectionSupplier
->select(uno::makeAny(xShapes
));
769 catch (lang::IllegalArgumentException
&)
771 SelectionChanged(); // find all selected shapes and set the flags
775 void ScChildrenShapes::FillShapes(std::vector
< uno::Reference
< drawing::XShape
> >& rShapes
) const
777 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
780 sal_uInt32
nCount(xShapes
->getCount());
781 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
783 uno::Reference
<drawing::XShape
> xShape
;
784 xShapes
->getByIndex(i
) >>= xShape
;
786 rShapes
.push_back(xShape
);
791 sal_Int32
ScChildrenShapes::GetSelectedCount() const
793 if (!xSelectionSupplier
.is())
794 throw uno::RuntimeException();
796 std::vector
< uno::Reference
< drawing::XShape
> > aShapes
;
799 return aShapes
.size();
802 uno::Reference
< XAccessible
> ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex
, bool bTabSelected
) const
804 uno::Reference
< XAccessible
> xAccessible
;
806 if (maZOrderedShapes
.size() <= 1)
807 GetCount(); // fill list with shapes
811 std::vector
< uno::Reference
< drawing::XShape
> > aShapes
;
814 if (nSelectedChildIndex
< 0 || o3tl::make_unsigned(nSelectedChildIndex
) >= aShapes
.size())
817 SortedShapes::iterator aItr
;
818 if (FindShape(aShapes
[nSelectedChildIndex
], aItr
))
819 xAccessible
= Get(*aItr
);
823 if (mbShapesNeedSorting
)
825 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
826 mbShapesNeedSorting
= false;
828 for(const auto& rpShape
: maZOrderedShapes
)
830 if (!rpShape
|| rpShape
->bSelected
)
832 if (nSelectedChildIndex
== 0)
835 xAccessible
= rpShape
->pAccShape
.get();
839 --nSelectedChildIndex
;
847 void ScChildrenShapes::Deselect(sal_Int32 nChildIndex
)
849 uno::Reference
<drawing::XShape
> xShape
;
850 if (!IsSelected(nChildIndex
, xShape
)) // returns false if it is the sheet
856 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
858 xShapes
->remove(xShape
);
862 xSelectionSupplier
->select(uno::makeAny(xShapes
));
864 catch (lang::IllegalArgumentException
&)
866 OSL_FAIL("something not selectable");
869 maZOrderedShapes
[nChildIndex
]->bSelected
= false;
870 if (maZOrderedShapes
[nChildIndex
]->pAccShape
.is())
871 maZOrderedShapes
[nChildIndex
]->pAccShape
->ResetState(AccessibleStateType::SELECTED
);
874 SdrPage
* ScChildrenShapes::GetDrawPage() const
876 SCTAB
nTab(mpAccessibleDocument
->getVisibleTable());
877 SdrPage
* pDrawPage
= nullptr;
880 ScDocument
& rDoc
= mpViewShell
->GetViewData().GetDocument();
881 if (ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer())
883 if (pDrawLayer
->HasObjects() && (pDrawLayer
->GetPageCount() > nTab
))
884 pDrawPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(static_cast<sal_Int16
>(nTab
)));
890 utl::AccessibleRelationSetHelper
* ScChildrenShapes::GetRelationSet(const ScAddress
* pAddress
) const
892 utl::AccessibleRelationSetHelper
* pRelationSet
= nullptr;
893 for (const ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
896 ((!pAccShapeData
->xRelationCell
&& !pAddress
) ||
897 (pAccShapeData
->xRelationCell
&& pAddress
&& (*(pAccShapeData
->xRelationCell
) == *pAddress
))))
900 pRelationSet
= new utl::AccessibleRelationSetHelper();
902 AccessibleRelation aRelation
;
903 aRelation
.TargetSet
.realloc(1);
904 aRelation
.TargetSet
[0] = Get(pAccShapeData
);
905 aRelation
.RelationType
= AccessibleRelationType::CONTROLLER_FOR
;
907 pRelationSet
->AddRelation(aRelation
);
913 bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference
<drawing::XShapes
>& xShapes
) const
916 SortedShapes aShapesList
;
919 mnShapesSelected
= xShapes
->getCount();
920 for (sal_uInt32 i
= 0; i
< mnShapesSelected
; ++i
)
922 uno::Reference
< drawing::XShape
> xShape
;
923 xShapes
->getByIndex(i
) >>= xShape
;
926 ScAccessibleShapeData
* pShapeData
= new ScAccessibleShapeData(xShape
);
927 aShapesList
.push_back(pShapeData
);
932 mnShapesSelected
= 0;
933 SdrObject
*pFocusedObj
= nullptr;
934 if( mnShapesSelected
== 1 && aShapesList
.size() == 1)
936 pFocusedObj
= GetSdrObjectFromXShape(aShapesList
[0]->xShape
);
938 std::sort(aShapesList
.begin(), aShapesList
.end(), ScShapeDataLess());
939 SortedShapes vecSelectedShapeAdd
;
940 SortedShapes vecSelectedShapeRemove
;
941 bool bHasSelect
=false;
942 SortedShapes::iterator
aXShapesItr(aShapesList
.begin());
943 SortedShapes::const_iterator
aXShapesEndItr(aShapesList
.end());
944 SortedShapes::iterator
aDataItr(maZOrderedShapes
.begin());
945 SortedShapes::const_iterator
aDataEndItr(maZOrderedShapes
.end());
946 SortedShapes::const_iterator aFocusedItr
= aDataEndItr
;
947 while(aDataItr
!= aDataEndItr
)
949 if (*aDataItr
) // is it really a shape or only the sheet
952 if (aXShapesItr
== aXShapesEndItr
)
953 nComp
= -1; // simulate that the Shape is lower, so the selection state will be removed
955 nComp
= Compare(*aDataItr
, *aXShapesItr
);
958 if (!(*aDataItr
)->bSelected
)
960 (*aDataItr
)->bSelected
= true;
961 if ((*aDataItr
)->pAccShape
.is())
963 (*aDataItr
)->pAccShape
->SetState(AccessibleStateType::SELECTED
);
964 (*aDataItr
)->pAccShape
->SetState(AccessibleStateType::FOCUSED
);
966 vecSelectedShapeAdd
.push_back(*aDataItr
);
968 aFocusedItr
= aDataItr
;
979 if ((*aDataItr
)->bSelected
)
981 (*aDataItr
)->bSelected
= false;
982 if ((*aDataItr
)->pAccShape
.is())
984 (*aDataItr
)->pAccShape
->ResetState(AccessibleStateType::SELECTED
);
985 (*aDataItr
)->pAccShape
->ResetState(AccessibleStateType::FOCUSED
);
987 vecSelectedShapeRemove
.push_back(*aDataItr
);
994 OSL_FAIL("here is a selected shape which is not in the childlist");
1002 bool bWinFocus
=false;
1005 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
1008 bWinFocus
= pWin
->HasFocus();
1011 const SdrMarkList
* pMarkList
= nullptr;
1012 SdrObject
* pMarkedObj
= nullptr;
1013 bool bIsFocuseMarked
= true;
1014 if( mpViewShell
&& mnShapesSelected
== 1 && bWinFocus
)
1016 ScDrawView
* pScDrawView
= mpViewShell
->GetViewData().GetScDrawView();
1019 if( pScDrawView
->GetMarkedObjectList().GetMarkCount() == 1 )
1021 pMarkList
= &(pScDrawView
->GetMarkedObjectList());
1022 pMarkedObj
= pMarkList
->GetMark(0)->GetMarkedSdrObj();
1023 uno::Reference
< drawing::XShape
> xMarkedXShape (pMarkedObj
->getUnoShape(), uno::UNO_QUERY
);
1024 if( aFocusedItr
!= aDataEndItr
&&
1025 (*aFocusedItr
)->xShape
.is() &&
1026 xMarkedXShape
.is() &&
1027 (*aFocusedItr
)->xShape
!= xMarkedXShape
)
1028 bIsFocuseMarked
= false;
1032 //if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape.is() && (mnShapesSelected == 1))
1033 if ( bIsFocuseMarked
&& (aFocusedItr
!= aDataEndItr
) && (*aFocusedItr
)->pAccShape
.is() && (mnShapesSelected
== 1) && bWinFocus
)
1035 (*aFocusedItr
)->pAccShape
->SetState(AccessibleStateType::FOCUSED
);
1037 else if( pFocusedObj
&& bWinFocus
&& pMarkList
&& pMarkList
->GetMarkCount() == 1 && mnShapesSelected
== 1 )
1041 uno::Reference
< drawing::XShape
> xMarkedXShape (pMarkedObj
->getUnoShape(), uno::UNO_QUERY
);
1042 SdrObject
* pUpObj
= pMarkedObj
->getParentSdrObjectFromSdrObject();
1044 if( pMarkedObj
== pFocusedObj
&& pUpObj
)
1046 uno::Reference
< drawing::XShape
> xUpGroupXShape (pUpObj
->getUnoShape(), uno::UNO_QUERY
);
1047 uno::Reference
< XAccessible
> xAccGroupShape
=
1048 const_cast<ScChildrenShapes
*>(this)->GetAccessibleCaption( xUpGroupXShape
);
1049 if( xAccGroupShape
.is() )
1051 ::accessibility::AccessibleShape
* pAccGroupShape
=
1052 static_cast< ::accessibility::AccessibleShape
* >(xAccGroupShape
.get());
1053 if( pAccGroupShape
)
1055 sal_Int32 nCount
= pAccGroupShape
->getAccessibleChildCount();
1056 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
1058 uno::Reference
<XAccessible
> xAccShape
= pAccGroupShape
->getAccessibleChild(i
);
1061 ::accessibility::AccessibleShape
* pChildAccShape
= static_cast< ::accessibility::AccessibleShape
* >(xAccShape
.get());
1062 uno::Reference
< drawing::XShape
> xChildShape
= pChildAccShape
->GetXShape();
1063 if (xChildShape
== xMarkedXShape
)
1065 pChildAccShape
->SetState(AccessibleStateType::FOCUSED
);
1069 pChildAccShape
->ResetState(AccessibleStateType::FOCUSED
);
1078 if (vecSelectedShapeAdd
.size() >= 10 )
1080 AccessibleEventObject aEvent
;
1081 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_WITHIN
;
1082 aEvent
.Source
= uno::Reference
< XAccessible
>(mpAccessibleDocument
);
1083 mpAccessibleDocument
->CommitChange(aEvent
);
1087 for (const auto& rpShape
: vecSelectedShapeAdd
)
1089 AccessibleEventObject aEvent
;
1092 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_ADD
;
1096 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED
;
1098 aEvent
.Source
= uno::Reference
< XAccessible
>(mpAccessibleDocument
);
1099 uno::Reference
< XAccessible
> xChild( rpShape
->pAccShape
.get());
1100 aEvent
.NewValue
<<= xChild
;
1101 mpAccessibleDocument
->CommitChange(aEvent
);
1104 for (const auto& rpShape
: vecSelectedShapeRemove
)
1106 AccessibleEventObject aEvent
;
1107 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_REMOVE
;
1108 aEvent
.Source
= uno::Reference
< XAccessible
>(mpAccessibleDocument
);
1109 uno::Reference
< XAccessible
> xChild( rpShape
->pAccShape
.get());
1110 aEvent
.NewValue
<<= xChild
;
1111 mpAccessibleDocument
->CommitChange(aEvent
);
1113 for(ScAccessibleShapeData
*& pShapeData
: aShapesList
)
1116 pShapeData
= nullptr;
1121 std::optional
<ScAddress
> ScChildrenShapes::GetAnchor(const uno::Reference
<drawing::XShape
>& xShape
) const
1125 SvxShape
* pShapeImp
= comphelper::getUnoTunnelImplementation
<SvxShape
>(xShape
);
1126 uno::Reference
<beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
1127 if (pShapeImp
&& xShapeProp
.is())
1129 if (SdrObject
*pSdrObj
= pShapeImp
->GetSdrObject())
1131 if (ScDrawObjData
*pAnchor
= ScDrawLayer::GetObjData(pSdrObj
))
1132 return std::optional
<ScAddress
>(pAnchor
->maStart
);
1137 return std::optional
<ScAddress
>();
1140 uno::Reference
<XAccessibleRelationSet
> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData
* pData
) const
1142 utl::AccessibleRelationSetHelper
* pRelationSet
= new utl::AccessibleRelationSetHelper();
1144 if (pData
&& mpAccessibleDocument
)
1146 uno::Reference
<XAccessible
> xAccessible
= mpAccessibleDocument
->GetAccessibleSpreadsheet(); // should be the current table
1147 if (pData
->xRelationCell
&& xAccessible
.is())
1149 sal_Int32 nRow
= pData
->xRelationCell
->Row();
1150 sal_Int32 nColumn
= pData
->xRelationCell
->Col();
1151 bool bPositionUnset
= nRow
== -1 && nColumn
== -1;
1152 if (!bPositionUnset
)
1154 uno::Reference
<XAccessibleTable
> xAccTable(xAccessible
->getAccessibleContext(), uno::UNO_QUERY
);
1156 xAccessible
= xAccTable
->getAccessibleCellAt(nRow
, nColumn
);
1159 AccessibleRelation aRelation
;
1160 aRelation
.TargetSet
.realloc(1);
1161 aRelation
.TargetSet
[0] = xAccessible
;
1162 aRelation
.RelationType
= AccessibleRelationType::CONTROLLED_BY
;
1163 pRelationSet
->AddRelation(aRelation
);
1166 return pRelationSet
;
1169 void ScChildrenShapes::SetAnchor(const uno::Reference
<drawing::XShape
>& xShape
, ScAccessibleShapeData
* pData
) const
1173 std::optional
<ScAddress
> xAddress
= GetAnchor(xShape
);
1174 if ((xAddress
&& pData
->xRelationCell
&& (*xAddress
!= *(pData
->xRelationCell
))) ||
1175 (!xAddress
&& pData
->xRelationCell
) || (xAddress
&& !pData
->xRelationCell
))
1177 pData
->xRelationCell
= xAddress
;
1178 if (pData
->pAccShape
.is())
1179 pData
->pAccShape
->SetRelationSet(GetRelationSet(pData
));
1184 void ScChildrenShapes::AddShape(const uno::Reference
<drawing::XShape
>& xShape
, bool bCommitChange
) const
1186 assert( maShapesMap
.find(xShape
) == maShapesMap
.end());
1188 ScAccessibleShapeData
* pShape
= new ScAccessibleShapeData(xShape
);
1189 maZOrderedShapes
.push_back(pShape
);
1190 mbShapesNeedSorting
= true;
1191 maShapesMap
[xShape
] = pShape
;
1192 SetAnchor(xShape
, pShape
);
1194 uno::Reference
< beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
1195 if (xShapeProp
.is())
1197 uno::Any aPropAny
= xShapeProp
->getPropertyValue("LayerID");
1198 sal_Int16 nLayerID
= 0;
1199 if( aPropAny
>>= nLayerID
)
1201 if( (SdrLayerID(nLayerID
) == SC_LAYER_INTERN
) || (SdrLayerID(nLayerID
) == SC_LAYER_HIDDEN
) )
1202 pShape
->bSelectable
= false;
1204 pShape
->bSelectable
= true;
1208 if (!xSelectionSupplier
.is())
1209 throw uno::RuntimeException();
1211 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
1212 uno::Reference
<container::XEnumerationAccess
> xEnumAcc(xShapes
, uno::UNO_QUERY
);
1215 uno::Reference
<container::XEnumeration
> xEnum
= xEnumAcc
->createEnumeration();
1218 uno::Reference
<drawing::XShape
> xSelectedShape
;
1220 while (!bFound
&& xEnum
->hasMoreElements())
1222 xEnum
->nextElement() >>= xSelectedShape
;
1223 if (xShape
.is() && (xShape
.get() == xSelectedShape
.get()))
1225 pShape
->bSelected
= true;
1231 if (mpAccessibleDocument
&& bCommitChange
)
1233 AccessibleEventObject aEvent
;
1234 aEvent
.EventId
= AccessibleEventId::CHILD
;
1235 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
1236 aEvent
.NewValue
<<= Get(pShape
);
1238 mpAccessibleDocument
->CommitChange(aEvent
); // new child - event
1242 void ScChildrenShapes::RemoveShape(const uno::Reference
<drawing::XShape
>& xShape
) const
1244 if (mbShapesNeedSorting
)
1246 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
1247 mbShapesNeedSorting
= false;
1249 SortedShapes::iterator aItr
;
1250 if (FindShape(xShape
, aItr
))
1252 if (mpAccessibleDocument
)
1254 uno::Reference
<XAccessible
> xOldAccessible (Get(*aItr
));
1257 maShapesMap
.erase((*aItr
)->xShape
);
1258 maZOrderedShapes
.erase(aItr
);
1260 AccessibleEventObject aEvent
;
1261 aEvent
.EventId
= AccessibleEventId::CHILD
;
1262 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
1263 aEvent
.OldValue
<<= xOldAccessible
;
1265 mpAccessibleDocument
->CommitChange(aEvent
); // child is gone - event
1270 maShapesMap
.erase((*aItr
)->xShape
);
1271 maZOrderedShapes
.erase(aItr
);
1276 OSL_FAIL("shape was not in internal list");
1280 bool ScChildrenShapes::FindShape(const uno::Reference
<drawing::XShape
>& xShape
, ScChildrenShapes::SortedShapes::iterator
& rItr
) const
1282 if (mbShapesNeedSorting
)
1284 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
1285 mbShapesNeedSorting
= false;
1287 bool bResult(false);
1288 ScAccessibleShapeData
aShape(xShape
);
1289 rItr
= std::lower_bound(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), &aShape
, ScShapeDataLess());
1290 if ((rItr
!= maZOrderedShapes
.end()) && (*rItr
!= nullptr) && ((*rItr
)->xShape
.get() == xShape
.get()))
1291 bResult
= true; // if the shape is found
1293 #if OSL_DEBUG_LEVEL > 0 // test whether it finds truly the correct shape (perhaps it is not really sorted)
1294 SortedShapes::iterator aDebugItr
= std::find_if(maZOrderedShapes
.begin(), maZOrderedShapes
.end(),
1295 [&xShape
](const ScAccessibleShapeData
* pShape
) { return pShape
&& (pShape
->xShape
.get() == xShape
.get()); });
1296 bool bResult2
= (aDebugItr
!= maZOrderedShapes
.end());
1297 OSL_ENSURE((bResult
== bResult2
) && ((bResult
&& (rItr
== aDebugItr
)) || !bResult
), "wrong Shape found");
1302 sal_Int8
ScChildrenShapes::Compare(const ScAccessibleShapeData
* pData1
,
1303 const ScAccessibleShapeData
* pData2
)
1305 ScShapeDataLess aLess
;
1307 bool bResult1(aLess(pData1
, pData2
));
1308 bool bResult2(aLess(pData2
, pData1
));
1310 sal_Int8
nResult(0);
1311 if (!bResult1
&& bResult2
)
1313 else if (bResult1
&& !bResult2
)
1319 void ScChildrenShapes::VisAreaChanged() const
1321 for (const ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
1322 if (pAccShapeData
&& pAccShapeData
->pAccShape
.is())
1323 pAccShapeData
->pAccShape
->ViewForwarderChanged();
1326 ScAccessibleDocument::ScAccessibleDocument(
1327 const uno::Reference
<XAccessible
>& rxParent
,
1328 ScTabViewShell
* pViewShell
,
1329 ScSplitPos eSplitPos
)
1330 : ScAccessibleDocumentBase(rxParent
),
1331 mpViewShell(pViewShell
),
1332 meSplitPos(eSplitPos
),
1333 mpTempAccEdit(nullptr),
1334 mbCompleteSheetSelected(false)
1336 maVisArea
= GetVisibleArea_Impl();
1339 void ScAccessibleDocument::PreInit()
1344 mpViewShell
->AddAccessibilityObject(*this);
1345 vcl::Window
*pWin
= mpViewShell
->GetWindowByPos(meSplitPos
);
1348 pWin
->AddChildEventListener( LINK( this, ScAccessibleDocument
, WindowChildEventListener
));
1349 sal_uInt16 nCount
= pWin
->GetChildCount();
1350 for( sal_uInt16 i
=0; i
< nCount
; ++i
)
1352 vcl::Window
*pChildWin
= pWin
->GetChild( i
);
1354 AccessibleRole::EMBEDDED_OBJECT
== pChildWin
->GetAccessibleRole() )
1355 AddChild( pChildWin
->GetAccessible(), false );
1358 ScViewData
& rViewData
= mpViewShell
->GetViewData();
1359 if (rViewData
.HasEditView(meSplitPos
))
1361 uno::Reference
<XAccessible
> xAcc
= new ScAccessibleEditObject(this, rViewData
.GetEditView(meSplitPos
),
1362 mpViewShell
->GetWindowByPos(meSplitPos
), GetCurrentCellName(), GetCurrentCellDescription(),
1363 ScAccessibleEditObject::CellInEditMode
);
1364 AddChild(xAcc
, false);
1368 void ScAccessibleDocument::Init()
1370 if(!mpChildrenShapes
)
1371 mpChildrenShapes
.reset( new ScChildrenShapes(this, mpViewShell
, meSplitPos
) );
1374 ScAccessibleDocument::~ScAccessibleDocument()
1376 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper
.bInDispose
)
1378 // increment refcount to prevent double call off dtor
1379 osl_atomic_increment( &m_refCount
);
1384 void SAL_CALL
ScAccessibleDocument::disposing()
1386 SolarMutexGuard aGuard
;
1387 FreeAccessibleSpreadsheet();
1390 vcl::Window
*pWin
= mpViewShell
->GetWindowByPos(meSplitPos
);
1392 pWin
->RemoveChildEventListener( LINK( this, ScAccessibleDocument
, WindowChildEventListener
));
1394 mpViewShell
->RemoveAccessibilityObject(*this);
1395 mpViewShell
= nullptr;
1397 mpChildrenShapes
.reset();
1399 ScAccessibleDocumentBase::disposing();
1402 void SAL_CALL
ScAccessibleDocument::disposing( const lang::EventObject
& /* Source */ )
1407 //===== SfxListener =====================================================
1409 IMPL_LINK( ScAccessibleDocument
, WindowChildEventListener
, VclWindowEvent
&, rEvent
, void )
1411 OSL_ENSURE( rEvent
.GetWindow(), "Window???" );
1412 switch ( rEvent
.GetId() )
1414 case VclEventId::WindowShow
: // send create on show for direct accessible children
1416 vcl::Window
* pChildWin
= static_cast < vcl::Window
* >( rEvent
.GetData() );
1417 if( pChildWin
&& AccessibleRole::EMBEDDED_OBJECT
== pChildWin
->GetAccessibleRole() )
1419 AddChild( pChildWin
->GetAccessible(), true );
1423 case VclEventId::WindowHide
: // send destroy on hide for direct accessible children
1425 vcl::Window
* pChildWin
= static_cast < vcl::Window
* >( rEvent
.GetData() );
1426 if( pChildWin
&& AccessibleRole::EMBEDDED_OBJECT
== pChildWin
->GetAccessibleRole() )
1428 RemoveChild( pChildWin
->GetAccessible(), true );
1436 void ScAccessibleDocument::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1438 if (auto pFocusLostHint
= dynamic_cast<const ScAccGridWinFocusLostHint
*>(&rHint
) )
1440 if (pFocusLostHint
->GetOldGridWin() == meSplitPos
)
1442 if (mxTempAcc
.is() && mpTempAccEdit
)
1443 mpTempAccEdit
->LostFocus();
1444 else if (mpAccessibleSpreadsheet
.is())
1445 mpAccessibleSpreadsheet
->LostFocus();
1450 else if (auto pFocusGotHint
= dynamic_cast<const ScAccGridWinFocusGotHint
*>(&rHint
) )
1452 if (pFocusGotHint
->GetNewGridWin() == meSplitPos
)
1454 uno::Reference
<XAccessible
> xAccessible
;
1455 if (mpChildrenShapes
)
1457 bool bTabMarked(IsTableSelected());
1458 xAccessible
= mpChildrenShapes
->GetSelected(0, bTabMarked
);
1460 if( xAccessible
.is() )
1463 aNewValue
<<=AccessibleStateType::FOCUSED
;
1464 static_cast< ::accessibility::AccessibleShape
* >(xAccessible
.get())->
1465 CommitChange(AccessibleEventId::STATE_CHANGED
,
1471 if (mxTempAcc
.is() && mpTempAccEdit
)
1472 mpTempAccEdit
->GotFocus();
1473 else if (mpAccessibleSpreadsheet
.is())
1474 mpAccessibleSpreadsheet
->GotFocus();
1476 CommitFocusGained();
1482 // only notify if child exist, otherwise it is not necessary
1483 if ((rHint
.GetId() == SfxHintId::ScAccTableChanged
) &&
1484 mpAccessibleSpreadsheet
.is())
1486 FreeAccessibleSpreadsheet();
1488 // Shapes / form controls after reload not accessible, rebuild the
1489 // mpChildrenShapes variable.
1490 mpChildrenShapes
.reset( new ScChildrenShapes( this, mpViewShell
, meSplitPos
) );
1492 AccessibleEventObject aEvent
;
1493 aEvent
.EventId
= AccessibleEventId::INVALIDATE_ALL_CHILDREN
;
1494 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1495 CommitChange(aEvent
); // all children changed
1497 if (mpAccessibleSpreadsheet
.is())
1498 mpAccessibleSpreadsheet
->FireFirstCellFocus();
1500 else if (rHint
.GetId() == SfxHintId::ScAccMakeDrawLayer
)
1502 if (mpChildrenShapes
)
1503 mpChildrenShapes
->SetDrawBroadcaster();
1505 else if (rHint
.GetId() == SfxHintId::ScAccEnterEditMode
) // this event comes only on creating edit field of a cell
1507 if (mpViewShell
->GetViewData().GetEditActivePart() == meSplitPos
)
1509 ScViewData
& rViewData
= mpViewShell
->GetViewData();
1510 const EditEngine
* pEditEng
= rViewData
.GetEditView(meSplitPos
)->GetEditEngine();
1511 if (pEditEng
&& pEditEng
->GetUpdateMode())
1513 mpTempAccEdit
= new ScAccessibleEditObject(this, rViewData
.GetEditView(meSplitPos
),
1514 mpViewShell
->GetWindowByPos(meSplitPos
), GetCurrentCellName(),
1515 ScResId(STR_ACC_EDITLINE_DESCR
), ScAccessibleEditObject::CellInEditMode
);
1516 uno::Reference
<XAccessible
> xAcc
= mpTempAccEdit
;
1518 AddChild(xAcc
, true);
1520 if (mpAccessibleSpreadsheet
.is())
1521 mpAccessibleSpreadsheet
->LostFocus();
1525 mpTempAccEdit
->GotFocus();
1529 else if (rHint
.GetId() == SfxHintId::ScAccLeaveEditMode
)
1535 mpTempAccEdit
->LostFocus();
1537 RemoveChild(mxTempAcc
, true);
1540 // tdf#125982 a11y use-after-free of editengine by
1541 // ScAccessibleEditObjectTextData living past the
1542 // the editengine of the editview passed in above
1543 // in ScAccEnterEditMode
1544 mpTempAccEdit
->dispose();
1545 mpTempAccEdit
= nullptr;
1547 if (mpAccessibleSpreadsheet
.is() && mpViewShell
&& mpViewShell
->IsActive())
1548 mpAccessibleSpreadsheet
->GotFocus();
1549 else if( mpViewShell
&& mpViewShell
->IsActive())
1550 CommitFocusGained();
1553 else if ((rHint
.GetId() == SfxHintId::ScAccVisAreaChanged
) || (rHint
.GetId() == SfxHintId::ScAccWindowResized
))
1555 tools::Rectangle
aOldVisArea(maVisArea
);
1556 maVisArea
= GetVisibleArea_Impl();
1558 if (maVisArea
!= aOldVisArea
)
1560 if (maVisArea
.GetSize() != aOldVisArea
.GetSize())
1562 AccessibleEventObject aEvent
;
1563 aEvent
.EventId
= AccessibleEventId::BOUNDRECT_CHANGED
;
1564 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1566 CommitChange(aEvent
);
1568 if (mpAccessibleSpreadsheet
.is())
1569 mpAccessibleSpreadsheet
->BoundingBoxChanged();
1570 if (mpAccessibleSpreadsheet
.is() && mpViewShell
&& mpViewShell
->IsActive())
1571 mpAccessibleSpreadsheet
->FireFirstCellFocus();
1573 else if (mpAccessibleSpreadsheet
.is())
1575 mpAccessibleSpreadsheet
->VisAreaChanged();
1577 if (mpChildrenShapes
)
1578 mpChildrenShapes
->VisAreaChanged();
1583 ScAccessibleDocumentBase::Notify(rBC
, rHint
);
1586 void SAL_CALL
ScAccessibleDocument::selectionChanged( const lang::EventObject
& /* aEvent */ )
1588 bool bSelectionChanged(false);
1589 if (mpAccessibleSpreadsheet
.is())
1591 bool bOldSelected(mbCompleteSheetSelected
);
1592 mbCompleteSheetSelected
= IsTableSelected();
1593 if (bOldSelected
!= mbCompleteSheetSelected
)
1595 mpAccessibleSpreadsheet
->CompleteSelectionChanged(mbCompleteSheetSelected
);
1596 bSelectionChanged
= true;
1600 if (mpChildrenShapes
&& mpChildrenShapes
->SelectionChanged())
1601 bSelectionChanged
= true;
1603 if (bSelectionChanged
)
1605 AccessibleEventObject aEvent
;
1606 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED
;
1607 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1609 CommitChange(aEvent
);
1613 //===== XInterface =====================================================
1615 uno::Any SAL_CALL
ScAccessibleDocument::queryInterface( uno::Type
const & rType
)
1617 uno::Any
aAny (ScAccessibleDocumentImpl::queryInterface(rType
));
1618 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
1621 void SAL_CALL
ScAccessibleDocument::acquire()
1624 ScAccessibleContextBase::acquire();
1627 void SAL_CALL
ScAccessibleDocument::release()
1630 ScAccessibleContextBase::release();
1633 //===== XAccessibleComponent ============================================
1635 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDocument::getAccessibleAtPoint(
1636 const awt::Point
& rPoint
)
1638 uno::Reference
<XAccessible
> xAccessible
;
1639 if (containsPoint(rPoint
))
1641 SolarMutexGuard aGuard
;
1643 if (mpChildrenShapes
)
1644 xAccessible
= mpChildrenShapes
->GetAt(rPoint
);
1645 if(!xAccessible
.is())
1649 uno::Reference
< XAccessibleContext
> xCont(mxTempAcc
->getAccessibleContext());
1650 uno::Reference
< XAccessibleComponent
> xComp(xCont
, uno::UNO_QUERY
);
1653 tools::Rectangle
aBound(VCLRectangle(xComp
->getBounds()));
1654 if (aBound
.IsInside(VCLPoint(rPoint
)))
1655 xAccessible
= mxTempAcc
;
1658 if (!xAccessible
.is())
1659 xAccessible
= GetAccessibleSpreadsheet();
1665 void SAL_CALL
ScAccessibleDocument::grabFocus( )
1667 SolarMutexGuard aGuard
;
1669 if (!getAccessibleParent().is())
1672 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
1673 if (xAccessibleComponent
.is())
1675 xAccessibleComponent
->grabFocus();
1676 // grab only focus if it does not have the focus and it is not hidden
1678 (mpViewShell
->GetViewData().GetActivePart() != meSplitPos
) &&
1679 mpViewShell
->GetWindowByPos(meSplitPos
)->IsVisible())
1681 mpViewShell
->ActivatePart(meSplitPos
);
1686 //===== XAccessibleContext ==============================================
1688 /// Return the number of currently visible children.
1690 ScAccessibleDocument::getAccessibleChildCount()
1692 SolarMutexGuard aGuard
;
1694 sal_Int32
nCount(1);
1695 if (mpChildrenShapes
)
1696 nCount
= mpChildrenShapes
->GetCount(); // returns the count of the shapes inclusive the table
1704 /// Return the specified child or NULL if index is invalid.
1705 uno::Reference
<XAccessible
> SAL_CALL
1706 ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex
)
1708 SolarMutexGuard aGuard
;
1710 uno::Reference
<XAccessible
> xAccessible
;
1713 sal_Int32
nCount(1);
1714 if (mpChildrenShapes
)
1716 xAccessible
= mpChildrenShapes
->Get(nIndex
); // returns NULL if it is the table or out of range
1717 nCount
= mpChildrenShapes
->GetCount(); //there is always a table
1719 if (!xAccessible
.is())
1721 if (nIndex
< nCount
)
1722 xAccessible
= GetAccessibleSpreadsheet();
1723 else if (nIndex
== nCount
&& mxTempAcc
.is())
1724 xAccessible
= mxTempAcc
;
1728 if (!xAccessible
.is())
1729 throw lang::IndexOutOfBoundsException();
1734 /// Return the set of current states.
1735 uno::Reference
<XAccessibleStateSet
> SAL_CALL
1736 ScAccessibleDocument::getAccessibleStateSet()
1738 SolarMutexGuard aGuard
;
1739 uno::Reference
<XAccessibleStateSet
> xParentStates
;
1740 if (getAccessibleParent().is())
1742 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
1743 xParentStates
= xParentContext
->getAccessibleStateSet();
1745 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
1746 if (IsDefunc(xParentStates
))
1747 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
1750 pStateSet
->AddState(AccessibleStateType::EDITABLE
);
1751 pStateSet
->AddState(AccessibleStateType::ENABLED
);
1752 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
1754 pStateSet
->AddState(AccessibleStateType::SHOWING
);
1756 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
1762 ScAccessibleDocument::getAccessibleName()
1766 OUString aName
= ScResId(STR_ACC_DOC_SPREADSHEET
);
1767 ScDocument
* pScDoc
= GetDocument();
1771 SfxObjectShell
* pObjSh
= pScDoc
->GetDocumentShell();
1776 SfxMedium
* pMed
= pObjSh
->GetMedium();
1778 aFileName
= pMed
->GetName();
1780 if (aFileName
.isEmpty())
1781 aFileName
= pObjSh
->GetTitle(SFX_TITLE_APINAME
);
1783 if (!aFileName
.isEmpty())
1786 if (pObjSh
->IsReadOnly())
1787 aReadOnly
= ScResId(STR_ACC_DOC_SPREADSHEET_READONLY
);
1789 aName
= aFileName
+ aReadOnly
+ " - " + aName
;
1794 ///===== XAccessibleSelection ===========================================
1797 ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex
)
1799 SolarMutexGuard aGuard
;
1802 if (!(mpChildrenShapes
&& mpViewShell
))
1805 sal_Int32
nCount(mpChildrenShapes
->GetCount()); // all shapes and the table
1808 if (nChildIndex
< 0 || nChildIndex
>= nCount
)
1809 throw lang::IndexOutOfBoundsException();
1811 uno::Reference
< XAccessible
> xAccessible
= mpChildrenShapes
->Get(nChildIndex
);
1812 if (xAccessible
.is())
1814 bool bWasTableSelected(IsTableSelected());
1815 mpChildrenShapes
->Select(nChildIndex
); // throws no lang::IndexOutOfBoundsException if Index is too high
1816 if (bWasTableSelected
)
1817 mpViewShell
->SelectAll();
1821 mpViewShell
->SelectAll();
1826 ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex
)
1828 SolarMutexGuard aGuard
;
1830 bool bResult(false);
1832 if (mpChildrenShapes
)
1834 sal_Int32
nCount(mpChildrenShapes
->GetCount()); // all shapes and the table
1837 if (nChildIndex
< 0 || nChildIndex
>= nCount
)
1838 throw lang::IndexOutOfBoundsException();
1840 uno::Reference
< XAccessible
> xAccessible
= mpChildrenShapes
->Get(nChildIndex
);
1841 if (xAccessible
.is())
1843 uno::Reference
<drawing::XShape
> xShape
;
1844 bResult
= mpChildrenShapes
->IsSelected(nChildIndex
, xShape
); // throws no lang::IndexOutOfBoundsException if Index is too high
1848 if (mxTempAcc
.is() && nChildIndex
== nCount
)
1851 bResult
= IsTableSelected();
1858 ScAccessibleDocument::clearAccessibleSelection( )
1860 SolarMutexGuard aGuard
;
1863 if (mpChildrenShapes
)
1864 mpChildrenShapes
->DeselectAll(); //deselects all (also the table)
1868 ScAccessibleDocument::selectAllAccessibleChildren( )
1870 SolarMutexGuard aGuard
;
1873 if (mpChildrenShapes
)
1874 mpChildrenShapes
->SelectAll();
1876 // select table after shapes, because while selecting shapes the table will be deselected
1879 mpViewShell
->SelectAll();
1884 ScAccessibleDocument::getSelectedAccessibleChildCount( )
1886 SolarMutexGuard aGuard
;
1888 sal_Int32
nCount(0);
1890 if (mpChildrenShapes
)
1891 nCount
= mpChildrenShapes
->GetSelectedCount();
1893 if (IsTableSelected())
1902 uno::Reference
<XAccessible
> SAL_CALL
1903 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
)
1905 SolarMutexGuard aGuard
;
1907 uno::Reference
<XAccessible
> xAccessible
;
1908 if (mpChildrenShapes
)
1910 sal_Int32
nCount(getSelectedAccessibleChildCount()); //all shapes and the table
1911 if (nSelectedChildIndex
< 0 || nSelectedChildIndex
>= nCount
)
1912 throw lang::IndexOutOfBoundsException();
1914 bool bTabMarked(IsTableSelected());
1916 if (mpChildrenShapes
)
1917 xAccessible
= mpChildrenShapes
->GetSelected(nSelectedChildIndex
, bTabMarked
); // throws no lang::IndexOutOfBoundsException if Index is too high
1918 if (mxTempAcc
.is() && nSelectedChildIndex
== nCount
- 1)
1919 xAccessible
= mxTempAcc
;
1920 else if (bTabMarked
)
1921 xAccessible
= GetAccessibleSpreadsheet();
1924 OSL_ENSURE(xAccessible
.is(), "here should always be an accessible object or an exception thrown");
1930 ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex
)
1932 SolarMutexGuard aGuard
;
1935 if (!(mpChildrenShapes
&& mpViewShell
))
1938 sal_Int32
nCount(mpChildrenShapes
->GetCount()); // all shapes and the table
1941 if (nChildIndex
< 0 || nChildIndex
>= nCount
)
1942 throw lang::IndexOutOfBoundsException();
1944 bool bTabMarked(IsTableSelected());
1946 uno::Reference
< XAccessible
> xAccessible
= mpChildrenShapes
->Get(nChildIndex
);
1947 if (xAccessible
.is())
1949 mpChildrenShapes
->Deselect(nChildIndex
); // throws no lang::IndexOutOfBoundsException if Index is too high
1951 mpViewShell
->SelectAll(); // select the table again
1953 else if (bTabMarked
)
1954 mpViewShell
->Unmark();
1957 //===== XServiceInfo ====================================================
1960 ScAccessibleDocument::getImplementationName()
1962 return "ScAccessibleDocument";
1965 uno::Sequence
< OUString
> SAL_CALL
1966 ScAccessibleDocument::getSupportedServiceNames()
1968 uno::Sequence
< OUString
> aSequence
= ScAccessibleContextBase::getSupportedServiceNames();
1969 sal_Int32
nOldSize(aSequence
.getLength());
1970 aSequence
.realloc(nOldSize
+ 1);
1972 aSequence
[nOldSize
] = "com.sun.star.AccessibleSpreadsheetDocumentView";
1977 //===== XTypeProvider =======================================================
1979 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessibleDocument::getTypes()
1981 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
1984 uno::Sequence
<sal_Int8
> SAL_CALL
1985 ScAccessibleDocument::getImplementationId()
1987 return css::uno::Sequence
<sal_Int8
>();
1990 ///===== IAccessibleViewForwarder ========================================
1992 tools::Rectangle
ScAccessibleDocument::GetVisibleArea_Impl() const
1994 tools::Rectangle
aVisRect(GetBoundingBox());
1998 Point
aPoint(mpViewShell
->GetViewData().GetPixPos(meSplitPos
)); // returns a negative Point
1999 aPoint
.setX(-aPoint
.getX());
2000 aPoint
.setY(-aPoint
.getY());
2001 aVisRect
.SetPos(aPoint
);
2003 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
2005 aVisRect
= pWin
->PixelToLogic(aVisRect
, pWin
->GetDrawMapMode());
2011 tools::Rectangle
ScAccessibleDocument::GetVisibleArea() const
2013 SolarMutexGuard aGuard
;
2018 Point
ScAccessibleDocument::LogicToPixel (const Point
& rPoint
) const
2020 SolarMutexGuard aGuard
;
2023 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
2026 aPoint
= pWin
->LogicToPixel(rPoint
, pWin
->GetDrawMapMode());
2027 aPoint
+= pWin
->GetWindowExtentsRelative(nullptr).TopLeft();
2032 Size
ScAccessibleDocument::LogicToPixel (const Size
& rSize
) const
2034 SolarMutexGuard aGuard
;
2037 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
2039 aSize
= pWin
->LogicToPixel(rSize
, pWin
->GetDrawMapMode());
2043 //===== internal ========================================================
2045 utl::AccessibleRelationSetHelper
* ScAccessibleDocument::GetRelationSet(const ScAddress
* pAddress
) const
2047 utl::AccessibleRelationSetHelper
* pRelationSet
= nullptr;
2048 if (mpChildrenShapes
)
2049 pRelationSet
= mpChildrenShapes
->GetRelationSet(pAddress
);
2050 return pRelationSet
;
2054 ScAccessibleDocument::createAccessibleDescription()
2056 return STR_ACC_DOC_DESCR
;
2060 ScAccessibleDocument::createAccessibleName()
2062 SolarMutexGuard aGuard
;
2064 OUString sName
= ScResId(STR_ACC_DOC_NAME
);
2065 sal_Int32
nNumber(sal_Int32(meSplitPos
) + 1);
2066 sName
+= OUString::number(nNumber
);
2070 tools::Rectangle
ScAccessibleDocument::GetBoundingBoxOnScreen() const
2072 tools::Rectangle aRect
;
2075 vcl::Window
* pWindow
= mpViewShell
->GetWindowByPos(meSplitPos
);
2077 aRect
= pWindow
->GetWindowExtentsRelative(nullptr);
2082 tools::Rectangle
ScAccessibleDocument::GetBoundingBox() const
2084 tools::Rectangle aRect
;
2087 vcl::Window
* pWindow
= mpViewShell
->GetWindowByPos(meSplitPos
);
2089 aRect
= pWindow
->GetWindowExtentsRelative(pWindow
->GetAccessibleParentWindow());
2094 SCTAB
ScAccessibleDocument::getVisibleTable() const
2096 SCTAB
nVisibleTable(0);
2098 nVisibleTable
= mpViewShell
->GetViewData().GetTabNo();
2099 return nVisibleTable
;
2102 uno::Reference
< XAccessible
>
2103 ScAccessibleDocument::GetAccessibleSpreadsheet()
2105 if (!mpAccessibleSpreadsheet
.is() && mpViewShell
)
2107 mpAccessibleSpreadsheet
= new ScAccessibleSpreadsheet(this, mpViewShell
, getVisibleTable(), meSplitPos
);
2108 mpAccessibleSpreadsheet
->Init();
2109 mbCompleteSheetSelected
= IsTableSelected();
2111 return mpAccessibleSpreadsheet
.get();
2114 void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2116 if (mpAccessibleSpreadsheet
.is())
2118 mpAccessibleSpreadsheet
->dispose();
2119 mpAccessibleSpreadsheet
.clear();
2123 bool ScAccessibleDocument::IsTableSelected() const
2125 bool bResult (false);
2128 SCTAB
nTab(getVisibleTable());
2129 //#103800#; use a copy of MarkData
2130 ScMarkData
aMarkData(mpViewShell
->GetViewData().GetMarkData());
2131 aMarkData
.MarkToMulti();
2132 ScDocument
* pDoc
= GetDocument();
2133 if (aMarkData
.IsAllMarked( ScRange( 0, 0, nTab
, pDoc
->MaxCol(), pDoc
->MaxRow(), nTab
)))
2139 bool ScAccessibleDocument::IsDefunc(
2140 const uno::Reference
<XAccessibleStateSet
>& rxParentStates
)
2142 return ScAccessibleContextBase::IsDefunc() || (mpViewShell
== nullptr) || !getAccessibleParent().is() ||
2143 (rxParentStates
.is() && rxParentStates
->contains(AccessibleStateType::DEFUNC
));
2146 void ScAccessibleDocument::AddChild(const uno::Reference
<XAccessible
>& xAcc
, bool bFireEvent
)
2148 OSL_ENSURE(!mxTempAcc
.is(), "this object should be removed before");
2154 AccessibleEventObject aEvent
;
2155 aEvent
.Source
= uno::Reference
<XAccessibleContext
>(this);
2156 aEvent
.EventId
= AccessibleEventId::CHILD
;
2157 aEvent
.NewValue
<<= mxTempAcc
;
2158 CommitChange( aEvent
);
2163 void ScAccessibleDocument::RemoveChild(const uno::Reference
<XAccessible
>& xAcc
, bool bFireEvent
)
2165 OSL_ENSURE(mxTempAcc
.is(), "this object should be added before");
2169 OSL_ENSURE(xAcc
.get() == mxTempAcc
.get(), "only the same object should be removed");
2172 AccessibleEventObject aEvent
;
2173 aEvent
.Source
= uno::Reference
<XAccessibleContext
>(this);
2174 aEvent
.EventId
= AccessibleEventId::CHILD
;
2175 aEvent
.OldValue
<<= mxTempAcc
;
2176 CommitChange( aEvent
);
2178 mxTempAcc
= nullptr;
2181 OUString
ScAccessibleDocument::GetCurrentCellName() const
2183 OUString
sName(ScResId(STR_ACC_CELL_NAME
));
2186 // Document not needed, because only the cell address, but not the tablename is needed
2187 OUString
sAddress(mpViewShell
->GetViewData().GetCurPos().Format(ScRefFlags::VALID
));
2188 sName
= sName
.replaceFirst("%1", sAddress
);
2193 OUString
ScAccessibleDocument::GetCurrentCellDescription()
2198 ScDocument
*ScAccessibleDocument::GetDocument() const
2200 return mpViewShell
? &mpViewShell
->GetViewData().GetDocument() : nullptr;
2203 ScAddress
ScAccessibleDocument::GetCurCellAddress() const
2205 return mpViewShell
? mpViewShell
->GetViewData().GetCurPos() : ScAddress();
2208 uno::Any SAL_CALL
ScAccessibleDocument::getExtendedAttributes()
2212 uno::Any anyAttribute
;
2214 sal_uInt16 sheetIndex
;
2215 OUString sSheetName
;
2216 sheetIndex
= getVisibleTable();
2217 if(GetDocument()==nullptr)
2218 return anyAttribute
;
2219 GetDocument()->GetName(sheetIndex
,sSheetName
);
2220 OUString sValue
= "page-name:" + sSheetName
+
2221 ";page-number:" + OUString::number(sheetIndex
+1) +
2222 ";total-pages:" + OUString::number(GetDocument()->GetTableCount()) + ";";
2223 anyAttribute
<<= sValue
;
2224 return anyAttribute
;
2227 sal_Int32 SAL_CALL
ScAccessibleDocument::getForeground( )
2229 return sal_Int32(COL_BLACK
);
2232 sal_Int32 SAL_CALL
ScAccessibleDocument::getBackground( )
2234 SolarMutexGuard aGuard
;
2236 return sal_Int32(SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR
).nColor
);
2239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */