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 <tools/gen.hxx>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdobj.hxx>
49 #include <svx/ShapeTypeHandler.hxx>
50 #include <svx/AccessibleShape.hxx>
51 #include <svx/AccessibleShapeTreeInfo.hxx>
52 #include <svx/AccessibleShapeInfo.hxx>
53 #include <svx/IAccessibleParent.hxx>
54 #include <comphelper/sequence.hxx>
55 #include <sfx2/viewfrm.hxx>
56 #include <sfx2/docfile.hxx>
57 #include <toolkit/helper/vclunohelper.hxx>
58 #include <unotools/accessiblerelationsethelper.hxx>
60 #include <vcl/svapp.hxx>
61 #include <vcl/unohelp.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>
82 using namespace ::com::sun::star
;
83 using namespace ::com::sun::star::accessibility
;
85 //===== internal ========================================================
89 struct ScAccessibleShapeData
91 ScAccessibleShapeData(css::uno::Reference
< css::drawing::XShape
> xShape_
);
92 ~ScAccessibleShapeData();
93 mutable rtl::Reference
< ::accessibility::AccessibleShape
> pAccShape
;
94 std::optional
<ScAddress
> xRelationCell
; // if it is NULL this shape is anchored on the table
95 css::uno::Reference
< css::drawing::XShape
> xShape
;
98 // cache these to make the sorting cheaper
99 std::optional
<sal_Int16
> mxLayerID
;
100 std::optional
<sal_Int32
> mxZOrder
;
105 ScAccessibleShapeData::ScAccessibleShapeData(css::uno::Reference
< css::drawing::XShape
> xShape_
)
106 : xShape(std::move(xShape_
)),
107 bSelected(false), bSelectable(true)
109 static constexpr OUStringLiteral gsLayerId
= u
"LayerID";
110 static constexpr OUStringLiteral gsZOrder
= u
"ZOrder";
111 uno::Reference
< beans::XPropertySet
> xProps(xShape
, uno::UNO_QUERY
);
114 uno::Any aAny
= xProps
->getPropertyValue(gsLayerId
);
116 if (aAny
>>= nLayerID
)
117 mxLayerID
= nLayerID
;
119 aAny
= xProps
->getPropertyValue(gsZOrder
);
120 if (aAny
>>= nZOrder
)
125 ScAccessibleShapeData::~ScAccessibleShapeData()
129 pAccShape
->dispose();
135 struct ScShapeDataLess
137 static void ConvertLayerId(sal_Int16
& rLayerID
) // changes the number of the LayerId so it the accessibility order
139 // note: MSVC 2017 ICE's if this is written as "switch" so use "if"
140 if (SC_LAYER_FRONT
.get() == rLayerID
)
144 else if (SC_LAYER_BACK
.get() == rLayerID
)
148 else if (SC_LAYER_INTERN
.get() == rLayerID
)
152 else if (SC_LAYER_CONTROLS
.get() == rLayerID
)
157 static bool LessThanSheet(const ScAccessibleShapeData
* pData
)
160 if (pData
->mxLayerID
)
162 if (SdrLayerID(*pData
->mxLayerID
) == SC_LAYER_BACK
)
167 bool operator()(const ScAccessibleShapeData
* pData1
, const ScAccessibleShapeData
* pData2
) const
170 if (pData1
&& pData2
)
172 if( pData1
->mxLayerID
&& pData2
->mxLayerID
)
174 sal_Int16 nLayerID1
= *pData1
->mxLayerID
;
175 sal_Int16 nLayerID2
= *pData2
->mxLayerID
;
176 if (nLayerID1
== nLayerID2
)
178 if ( pData1
->mxZOrder
&& pData2
->mxZOrder
)
179 bResult
= (*pData1
->mxZOrder
< *pData2
->mxZOrder
);
183 ConvertLayerId(nLayerID1
);
184 ConvertLayerId(nLayerID2
);
185 bResult
= (nLayerID1
< nLayerID2
);
189 else if (pData1
&& !pData2
)
190 bResult
= LessThanSheet(pData1
);
191 else if (!pData1
&& pData2
)
192 bResult
= !LessThanSheet(pData2
);
201 class ScChildrenShapes
: public SfxListener
,
202 public ::accessibility::IAccessibleParent
205 ScChildrenShapes(ScAccessibleDocument
* pAccessibleDocument
, ScTabViewShell
* pViewShell
, ScSplitPos eSplitPos
);
206 virtual ~ScChildrenShapes() override
;
208 ///===== SfxListener =====================================================
210 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
212 ///===== IAccessibleParent ===============================================
214 virtual bool ReplaceChild (
215 ::accessibility::AccessibleShape
* pCurrentChild
,
216 const css::uno::Reference
< css::drawing::XShape
>& _rxShape
,
217 const tools::Long _nIndex
,
218 const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
221 virtual ::accessibility::AccessibleControlShape
* GetAccControlShapeFromModel
222 (css::beans::XPropertySet
* pSet
) override
;
223 virtual css::uno::Reference
< css::accessibility::XAccessible
>
224 GetAccessibleCaption (const css::uno::Reference
<css::drawing::XShape
>& xShape
) override
;
225 ///===== Internal ========================================================
226 void SetDrawBroadcaster();
228 sal_Int32
GetCount() const;
229 uno::Reference
< XAccessible
> Get(const ScAccessibleShapeData
* pData
) const;
230 uno::Reference
< XAccessible
> Get(sal_Int32 nIndex
) const;
231 uno::Reference
< XAccessible
> GetAt(const awt::Point
& rPoint
) const;
233 // gets the index of the shape starting on 0 (without the index of the table)
234 // returns the selected shape
235 bool IsSelected(sal_Int32 nIndex
,
236 css::uno::Reference
<css::drawing::XShape
>& rShape
) const;
238 bool SelectionChanged();
240 void Select(sal_Int32 nIndex
);
241 void DeselectAll(); // deselect also the table
243 sal_Int32
GetSelectedCount() const;
244 uno::Reference
< XAccessible
> GetSelected(sal_Int32 nSelectedChildIndex
, bool bTabSelected
) const;
245 void Deselect(sal_Int32 nChildIndex
);
247 SdrPage
* GetDrawPage() const;
249 rtl::Reference
<utl::AccessibleRelationSetHelper
> GetRelationSet(const ScAddress
* pAddress
) const;
251 void VisAreaChanged() const;
253 typedef std::vector
<ScAccessibleShapeData
*> SortedShapes
;
254 typedef std::unordered_map
<css::uno::Reference
< css::drawing::XShape
>, ScAccessibleShapeData
*> ShapesMap
;
256 mutable SortedShapes maZOrderedShapes
; // a null pointer represents the sheet in the correct order
257 mutable ShapesMap maShapesMap
;
258 mutable bool mbShapesNeedSorting
; // set if maZOrderedShapes needs sorting
260 mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo
;
261 mutable css::uno::Reference
<css::view::XSelectionSupplier
> xSelectionSupplier
;
262 mutable sal_uInt32 mnShapesSelected
;
263 ScTabViewShell
* mpViewShell
;
264 ScAccessibleDocument
* mpAccessibleDocument
;
265 ScSplitPos meSplitPos
;
267 void FillShapes(std::vector
< uno::Reference
< drawing::XShape
> >& rShapes
) const;
268 bool FindSelectedShapesChanges(const css::uno::Reference
<css::drawing::XShapes
>& xShapes
) const;
270 std::optional
<ScAddress
> GetAnchor(const uno::Reference
<drawing::XShape
>& xShape
) const;
271 rtl::Reference
<utl::AccessibleRelationSetHelper
> GetRelationSet(const ScAccessibleShapeData
* pData
) const;
272 void SetAnchor(const uno::Reference
<drawing::XShape
>& xShape
, ScAccessibleShapeData
* pData
) const;
273 void AddShape(const uno::Reference
<drawing::XShape
>& xShape
, bool bCommitChange
) const;
274 void RemoveShape(const uno::Reference
<drawing::XShape
>& xShape
) const;
276 bool FindShape(const uno::Reference
<drawing::XShape
>& xShape
, SortedShapes::iterator
& rItr
) const;
278 static sal_Int8
Compare(const ScAccessibleShapeData
* pData1
,
279 const ScAccessibleShapeData
* pData2
);
282 ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument
* pAccessibleDocument
, ScTabViewShell
* pViewShell
, ScSplitPos eSplitPos
)
284 mbShapesNeedSorting(false),
286 mpViewShell(pViewShell
),
287 mpAccessibleDocument(pAccessibleDocument
),
288 meSplitPos(eSplitPos
)
292 SfxViewFrame
& rViewFrame
= mpViewShell
->GetViewFrame();
293 xSelectionSupplier
= uno::Reference
<view::XSelectionSupplier
>(rViewFrame
.GetFrame().GetController(), uno::UNO_QUERY
);
294 if (xSelectionSupplier
.is())
296 xSelectionSupplier
->addSelectionChangeListener(mpAccessibleDocument
);
297 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
299 mnShapesSelected
= xShapes
->getCount();
303 maZOrderedShapes
.push_back(nullptr); // add an element which represents the table
305 GetCount(); // fill list with filtered shapes (no internal shapes)
307 if (mnShapesSelected
)
309 //set flag on every selected shape
310 if (!xSelectionSupplier
.is())
311 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::ScChildrenShapes.");
313 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
315 FindSelectedShapesChanges(xShapes
);
320 ScViewData
& rViewData
= pViewShell
->GetViewData();
321 SfxBroadcaster
* pDrawBC
= rViewData
.GetDocument().GetDrawBroadcaster();
324 StartListening(*pDrawBC
);
326 maShapeTreeInfo
.SetModelBroadcaster( new ScDrawModelBroadcaster(rViewData
.GetDocument().GetDrawLayer()) );
327 maShapeTreeInfo
.SetSdrView(rViewData
.GetScDrawView());
328 maShapeTreeInfo
.SetController(nullptr);
329 maShapeTreeInfo
.SetWindow(pViewShell
->GetWindowByPos(meSplitPos
));
330 maShapeTreeInfo
.SetViewForwarder(mpAccessibleDocument
);
334 ScChildrenShapes::~ScChildrenShapes()
336 for (ScAccessibleShapeData
* pShapeData
: maZOrderedShapes
)
340 SfxBroadcaster
* pDrawBC
= mpViewShell
->GetViewData().GetDocument().GetDrawBroadcaster();
342 EndListening(*pDrawBC
);
344 if (mpAccessibleDocument
&& xSelectionSupplier
.is())
345 xSelectionSupplier
->removeSelectionChangeListener(mpAccessibleDocument
);
348 void ScChildrenShapes::SetDrawBroadcaster()
353 ScViewData
& rViewData
= mpViewShell
->GetViewData();
354 SfxBroadcaster
* pDrawBC
= rViewData
.GetDocument().GetDrawBroadcaster();
357 StartListening(*pDrawBC
, DuplicateHandling::Prevent
);
359 maShapeTreeInfo
.SetModelBroadcaster( new ScDrawModelBroadcaster(rViewData
.GetDocument().GetDrawLayer()) );
360 maShapeTreeInfo
.SetSdrView(rViewData
.GetScDrawView());
361 maShapeTreeInfo
.SetController(nullptr);
362 maShapeTreeInfo
.SetWindow(mpViewShell
->GetWindowByPos(meSplitPos
));
363 maShapeTreeInfo
.SetViewForwarder(mpAccessibleDocument
);
367 void ScChildrenShapes::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
369 if (rHint
.GetId() != SfxHintId::ThisIsAnSdrHint
)
371 const SdrHint
* pSdrHint
= static_cast<const SdrHint
*>(&rHint
);
373 SdrObject
* pObj
= const_cast<SdrObject
*>(pSdrHint
->GetObject());
374 if (!(pObj
&& /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj
->getSdrPageFromSdrObject() == GetDrawPage()) &&
375 (pObj
->getSdrPageFromSdrObject() == pObj
->getParentSdrObjListFromSdrObject())) ) //only do something if the object lies direct on the page
378 switch (pSdrHint
->GetKind())
380 case SdrHintKind::ObjectChange
: // object changed
382 uno::Reference
<drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
385 mbShapesNeedSorting
= true; // sort, because the z index or layer could be changed
386 auto it
= maShapesMap
.find(xShape
);
387 if (it
!= maShapesMap
.end())
388 SetAnchor(xShape
, it
->second
);
392 case SdrHintKind::ObjectInserted
: // new drawing object inserted
394 uno::Reference
<drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
396 AddShape(xShape
, true);
399 case SdrHintKind::ObjectRemoved
: // Removed drawing object from list
401 uno::Reference
<drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
408 // other events are not interesting
414 bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape
* pCurrentChild
,
415 const css::uno::Reference
< css::drawing::XShape
>& _rxShape
,
416 const tools::Long
/*_nIndex*/, const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
)
418 // create the new child
419 rtl::Reference
< ::accessibility::AccessibleShape
> pReplacement(::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
420 ::accessibility::AccessibleShapeInfo ( _rxShape
, pCurrentChild
->getAccessibleParent(), this ),
425 if (pReplacement
.is())
427 OSL_ENSURE(pCurrentChild
->GetXShape().get() == pReplacement
->GetXShape().get(), "XShape changes and should be inserted sorted");
428 auto it
= maShapesMap
.find(pCurrentChild
->GetXShape());
429 if (it
!= maShapesMap
.end() && it
->second
->pAccShape
.is())
431 OSL_ENSURE(it
->second
->pAccShape
== pCurrentChild
, "wrong child found");
432 AccessibleEventObject aEvent
;
433 aEvent
.EventId
= AccessibleEventId::CHILD
;
434 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
435 aEvent
.OldValue
<<= uno::Reference
<XAccessible
>(pCurrentChild
);
436 aEvent
.IndexHint
= -1;
438 mpAccessibleDocument
->CommitChange(aEvent
); // child is gone - event
440 pCurrentChild
->dispose();
443 // Init after above possible pCurrentChild->dispose so we don't trigger the assert
444 // ScDrawModelBroadcaster::addShapeEventListener of duplicate listeners
445 pReplacement
->Init();
447 if (it
!= maShapesMap
.end())
449 it
->second
->pAccShape
= pReplacement
;
450 AccessibleEventObject aEvent
;
451 aEvent
.EventId
= AccessibleEventId::CHILD
;
452 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
453 aEvent
.NewValue
<<= uno::Reference
<XAccessible
>(pReplacement
);
454 aEvent
.IndexHint
= -1;
456 mpAccessibleDocument
->CommitChange(aEvent
); // child is new - event
463 ::accessibility::AccessibleControlShape
* ScChildrenShapes::GetAccControlShapeFromModel(css::beans::XPropertySet
* pSet
)
465 GetCount(); // populate
466 for (ScAccessibleShapeData
* pShape
: maZOrderedShapes
)
470 rtl::Reference
< ::accessibility::AccessibleShape
> pAccShape(pShape
->pAccShape
);
471 if (pAccShape
.is() && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape
->GetXShape()) == ::accessibility::DRAWING_CONTROL
)
473 ::accessibility::AccessibleControlShape
*pCtlAccShape
= static_cast < ::accessibility::AccessibleControlShape
* >(pAccShape
.get());
474 if (pCtlAccShape
&& pCtlAccShape
->GetControlModel() == pSet
)
482 css::uno::Reference
< css::accessibility::XAccessible
>
483 ScChildrenShapes::GetAccessibleCaption (const css::uno::Reference
< css::drawing::XShape
>& xShape
)
485 GetCount(); // populate
486 auto it
= maShapesMap
.find(xShape
);
487 if (it
== maShapesMap
.end())
489 ScAccessibleShapeData
* pShape
= it
->second
;
490 css::uno::Reference
< css::accessibility::XAccessible
> xNewChild( pShape
->pAccShape
);
496 sal_Int32
ScChildrenShapes::GetCount() const
498 SdrPage
* pDrawPage
= GetDrawPage();
499 if (pDrawPage
&& (maZOrderedShapes
.size() == 1)) // the table is always in
501 size_t nSdrObjCount
= pDrawPage
->GetObjCount();
502 maZOrderedShapes
.reserve(nSdrObjCount
+ 1); // the table is always in
503 for (const rtl::Reference
<SdrObject
>& pObj
: *pDrawPage
)
505 uno::Reference
< drawing::XShape
> xShape (pObj
->getUnoShape(), uno::UNO_QUERY
);
506 AddShape(xShape
, false); //inserts in the correct order
509 return maZOrderedShapes
.size();
512 uno::Reference
< XAccessible
> ScChildrenShapes::Get(const ScAccessibleShapeData
* pData
) const
517 if (!pData
->pAccShape
.is())
519 ::accessibility::ShapeTypeHandler
& rShapeHandler
= ::accessibility::ShapeTypeHandler::Instance();
520 ::accessibility::AccessibleShapeInfo
aShapeInfo(pData
->xShape
, mpAccessibleDocument
, const_cast<ScChildrenShapes
*>(this));
521 pData
->pAccShape
= rShapeHandler
.CreateAccessibleObject(
522 aShapeInfo
, maShapeTreeInfo
);
523 if (pData
->pAccShape
.is())
525 pData
->pAccShape
->Init();
526 if (pData
->bSelected
)
527 pData
->pAccShape
->SetState(AccessibleStateType::SELECTED
);
528 if (!pData
->bSelectable
)
529 pData
->pAccShape
->ResetState(AccessibleStateType::SELECTABLE
);
530 pData
->pAccShape
->SetRelationSet(GetRelationSet(pData
));
533 return pData
->pAccShape
;
536 uno::Reference
< XAccessible
> ScChildrenShapes::Get(sal_Int32 nIndex
) const
538 if (maZOrderedShapes
.size() <= 1)
539 GetCount(); // fill list with filtered shapes (no internal shapes)
541 if (mbShapesNeedSorting
)
543 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
544 mbShapesNeedSorting
= false;
547 if (o3tl::make_unsigned(nIndex
) >= maZOrderedShapes
.size())
550 return Get(maZOrderedShapes
[nIndex
]);
553 uno::Reference
< XAccessible
> ScChildrenShapes::GetAt(const awt::Point
& rPoint
) const
555 uno::Reference
<XAccessible
> xAccessible
;
558 if (mbShapesNeedSorting
)
560 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
561 mbShapesNeedSorting
= false;
564 sal_Int32
i(maZOrderedShapes
.size() - 1);
566 while (!bFound
&& i
>= 0)
568 ScAccessibleShapeData
* pShape
= maZOrderedShapes
[i
];
571 if (!pShape
->pAccShape
.is())
574 if (pShape
->pAccShape
.is())
576 Point
aPoint(vcl::unohelper::ConvertToVCLPoint(rPoint
));
578 -= vcl::unohelper::ConvertToVCLRect(pShape
->pAccShape
->getBounds()).TopLeft();
579 if (pShape
->pAccShape
->containsPoint(vcl::unohelper::ConvertToAWTPoint(aPoint
)))
581 xAccessible
= pShape
->pAccShape
.get();
587 OSL_FAIL("I should have an accessible shape now!");
591 bFound
= true; // this is the sheet and it lies before the rest of the shapes which are background shapes
599 bool ScChildrenShapes::IsSelected(sal_Int32 nIndex
,
600 uno::Reference
<drawing::XShape
>& rShape
) const
602 bool bResult (false);
603 if (maZOrderedShapes
.size() <= 1)
604 GetCount(); // fill list with filtered shapes (no internal shapes)
606 if (!xSelectionSupplier
.is())
607 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::IsSelected.");
609 if (mbShapesNeedSorting
)
611 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
612 mbShapesNeedSorting
= false;
615 if (!maZOrderedShapes
[nIndex
])
618 bResult
= maZOrderedShapes
[nIndex
]->bSelected
;
619 rShape
= maZOrderedShapes
[nIndex
]->xShape
;
621 #if OSL_DEBUG_LEVEL > 0 // test whether it is truly selected by a slower method
622 uno::Reference
< drawing::XShape
> xReturnShape
;
623 bool bDebugResult(false);
624 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
628 sal_Int32
nCount(xShapes
->getCount());
631 uno::Reference
< drawing::XShape
> xShape
;
632 uno::Reference
< drawing::XShape
> xIndexShape
= maZOrderedShapes
[nIndex
]->xShape
;
634 while (!bDebugResult
&& (i
< nCount
))
636 xShapes
->getByIndex(i
) >>= xShape
;
637 if (xShape
.is() && (xIndexShape
.get() == xShape
.get()))
640 xReturnShape
= xShape
;
647 OSL_ENSURE((bResult
== bDebugResult
) && ((bResult
&& (rShape
.get() == xReturnShape
.get())) || !bResult
), "found the wrong shape or result");
653 bool ScChildrenShapes::SelectionChanged()
656 if (!xSelectionSupplier
.is())
657 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::SelectionChanged.");
659 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
661 bResult
= FindSelectedShapesChanges(xShapes
);
666 void ScChildrenShapes::Select(sal_Int32 nIndex
)
668 if (maZOrderedShapes
.size() <= 1)
669 GetCount(); // fill list with filtered shapes (no internal shapes)
671 if (!xSelectionSupplier
.is())
672 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::Select.");
674 if (mbShapesNeedSorting
)
676 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
677 mbShapesNeedSorting
= false;
680 if (!maZOrderedShapes
[nIndex
])
683 uno::Reference
<drawing::XShape
> xShape
;
684 if (IsSelected(nIndex
, xShape
) || !maZOrderedShapes
[nIndex
]->bSelectable
)
687 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
690 xShapes
= drawing::ShapeCollection::create(
691 comphelper::getProcessComponentContext());
693 xShapes
->add(maZOrderedShapes
[nIndex
]->xShape
);
697 xSelectionSupplier
->select(uno::Any(xShapes
));
698 maZOrderedShapes
[nIndex
]->bSelected
= true;
699 if (maZOrderedShapes
[nIndex
]->pAccShape
.is())
700 maZOrderedShapes
[nIndex
]->pAccShape
->SetState(AccessibleStateType::SELECTED
);
702 catch (lang::IllegalArgumentException
&)
707 void ScChildrenShapes::DeselectAll()
709 if (!xSelectionSupplier
.is())
710 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::DeselectAll.");
712 bool bSomethingSelected(true);
715 xSelectionSupplier
->select(uno::Any()); //deselects all
717 catch (lang::IllegalArgumentException
&)
719 OSL_FAIL("nothing selected before");
720 bSomethingSelected
= false;
723 if (bSomethingSelected
)
724 for (ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
727 pAccShapeData
->bSelected
= false;
728 if (pAccShapeData
->pAccShape
.is())
729 pAccShapeData
->pAccShape
->ResetState(AccessibleStateType::SELECTED
);
734 void ScChildrenShapes::SelectAll()
736 if (!xSelectionSupplier
.is())
737 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::SelectAll.");
739 if (maZOrderedShapes
.size() <= 1)
740 GetCount(); // fill list with filtered shapes (no internal shapes)
742 if (maZOrderedShapes
.size() <= 1)
745 uno::Reference
<drawing::XShapes
> xShapes
= drawing::ShapeCollection::create(
746 comphelper::getProcessComponentContext());
750 for (ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
752 if (pAccShapeData
&& pAccShapeData
->bSelectable
)
754 pAccShapeData
->bSelected
= true;
755 if (pAccShapeData
->pAccShape
.is())
756 pAccShapeData
->pAccShape
->SetState(AccessibleStateType::SELECTED
);
758 xShapes
->add(pAccShapeData
->xShape
);
761 xSelectionSupplier
->select(uno::Any(xShapes
));
763 catch (lang::IllegalArgumentException
&)
765 SelectionChanged(); // find all selected shapes and set the flags
769 void ScChildrenShapes::FillShapes(std::vector
< uno::Reference
< drawing::XShape
> >& rShapes
) const
771 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
774 sal_uInt32
nCount(xShapes
->getCount());
775 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
777 uno::Reference
<drawing::XShape
> xShape
;
778 xShapes
->getByIndex(i
) >>= xShape
;
780 rShapes
.push_back(xShape
);
785 sal_Int32
ScChildrenShapes::GetSelectedCount() const
787 if (!xSelectionSupplier
.is())
788 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::GetSelectedCount.");
790 std::vector
< uno::Reference
< drawing::XShape
> > aShapes
;
793 return aShapes
.size();
796 uno::Reference
< XAccessible
> ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex
, bool bTabSelected
) const
798 uno::Reference
< XAccessible
> xAccessible
;
800 if (maZOrderedShapes
.size() <= 1)
801 GetCount(); // fill list with shapes
805 std::vector
< uno::Reference
< drawing::XShape
> > aShapes
;
808 if (nSelectedChildIndex
< 0 || o3tl::make_unsigned(nSelectedChildIndex
) >= aShapes
.size())
811 SortedShapes::iterator aItr
;
812 if (FindShape(aShapes
[nSelectedChildIndex
], aItr
))
813 xAccessible
= Get(*aItr
);
817 if (mbShapesNeedSorting
)
819 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
820 mbShapesNeedSorting
= false;
822 for(const auto& rpShape
: maZOrderedShapes
)
824 if (!rpShape
|| rpShape
->bSelected
)
826 if (nSelectedChildIndex
== 0)
829 xAccessible
= rpShape
->pAccShape
.get();
833 --nSelectedChildIndex
;
841 void ScChildrenShapes::Deselect(sal_Int32 nChildIndex
)
843 uno::Reference
<drawing::XShape
> xShape
;
844 if (!IsSelected(nChildIndex
, xShape
)) // returns false if it is the sheet
850 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
852 xShapes
->remove(xShape
);
856 xSelectionSupplier
->select(uno::Any(xShapes
));
858 catch (lang::IllegalArgumentException
&)
860 OSL_FAIL("something not selectable");
863 maZOrderedShapes
[nChildIndex
]->bSelected
= false;
864 if (maZOrderedShapes
[nChildIndex
]->pAccShape
.is())
865 maZOrderedShapes
[nChildIndex
]->pAccShape
->ResetState(AccessibleStateType::SELECTED
);
868 SdrPage
* ScChildrenShapes::GetDrawPage() const
870 SCTAB
nTab(mpAccessibleDocument
->getVisibleTable());
871 SdrPage
* pDrawPage
= nullptr;
874 ScDocument
& rDoc
= mpViewShell
->GetViewData().GetDocument();
875 if (ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer())
877 if (pDrawLayer
->HasObjects() && (pDrawLayer
->GetPageCount() > nTab
))
878 pDrawPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(static_cast<sal_Int16
>(nTab
)));
884 rtl::Reference
<utl::AccessibleRelationSetHelper
> ScChildrenShapes::GetRelationSet(const ScAddress
* pAddress
) const
886 rtl::Reference
<utl::AccessibleRelationSetHelper
> pRelationSet
;
887 for (const ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
890 ((!pAccShapeData
->xRelationCell
&& !pAddress
) ||
891 (pAccShapeData
->xRelationCell
&& pAddress
&& (*(pAccShapeData
->xRelationCell
) == *pAddress
))))
894 pRelationSet
= new utl::AccessibleRelationSetHelper();
896 AccessibleRelation aRelation
;
897 aRelation
.TargetSet
= { Get(pAccShapeData
) };
898 aRelation
.RelationType
= AccessibleRelationType_CONTROLLER_FOR
;
900 pRelationSet
->AddRelation(aRelation
);
906 bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference
<drawing::XShapes
>& xShapes
) const
909 SortedShapes aShapesList
;
912 mnShapesSelected
= xShapes
->getCount();
913 for (sal_uInt32 i
= 0; i
< mnShapesSelected
; ++i
)
915 uno::Reference
< drawing::XShape
> xShape
;
916 xShapes
->getByIndex(i
) >>= xShape
;
919 ScAccessibleShapeData
* pShapeData
= new ScAccessibleShapeData(xShape
);
920 aShapesList
.push_back(pShapeData
);
925 mnShapesSelected
= 0;
926 SdrObject
*pFocusedObj
= nullptr;
927 if( mnShapesSelected
== 1 && aShapesList
.size() == 1)
929 pFocusedObj
= SdrObject::getSdrObjectFromXShape(aShapesList
[0]->xShape
);
931 std::sort(aShapesList
.begin(), aShapesList
.end(), ScShapeDataLess());
932 SortedShapes vecSelectedShapeAdd
;
933 SortedShapes vecSelectedShapeRemove
;
934 bool bHasSelect
=false;
935 SortedShapes::iterator
aXShapesItr(aShapesList
.begin());
936 SortedShapes::const_iterator
aXShapesEndItr(aShapesList
.end());
937 SortedShapes::iterator
aDataItr(maZOrderedShapes
.begin());
938 SortedShapes::const_iterator
aDataEndItr(maZOrderedShapes
.end());
939 SortedShapes::const_iterator aFocusedItr
= aDataEndItr
;
940 while(aDataItr
!= aDataEndItr
)
942 if (*aDataItr
) // is it really a shape or only the sheet
945 if (aXShapesItr
== aXShapesEndItr
)
946 nComp
= -1; // simulate that the Shape is lower, so the selection state will be removed
948 nComp
= Compare(*aDataItr
, *aXShapesItr
);
951 if (!(*aDataItr
)->bSelected
)
953 (*aDataItr
)->bSelected
= true;
954 if ((*aDataItr
)->pAccShape
.is())
956 (*aDataItr
)->pAccShape
->SetState(AccessibleStateType::SELECTED
);
957 (*aDataItr
)->pAccShape
->SetState(AccessibleStateType::FOCUSED
);
959 vecSelectedShapeAdd
.push_back(*aDataItr
);
961 aFocusedItr
= aDataItr
;
972 if ((*aDataItr
)->bSelected
)
974 (*aDataItr
)->bSelected
= false;
975 if ((*aDataItr
)->pAccShape
.is())
977 (*aDataItr
)->pAccShape
->ResetState(AccessibleStateType::SELECTED
);
978 (*aDataItr
)->pAccShape
->ResetState(AccessibleStateType::FOCUSED
);
980 vecSelectedShapeRemove
.push_back(*aDataItr
);
987 OSL_FAIL("here is a selected shape which is not in the childlist");
995 bool bWinFocus
=false;
998 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
1001 bWinFocus
= pWin
->HasFocus();
1004 const SdrMarkList
* pMarkList
= nullptr;
1005 SdrObject
* pMarkedObj
= nullptr;
1006 bool bIsFocuseMarked
= true;
1007 if( mpViewShell
&& mnShapesSelected
== 1 && bWinFocus
)
1009 ScDrawView
* pScDrawView
= mpViewShell
->GetViewData().GetScDrawView();
1012 pMarkList
= &(pScDrawView
->GetMarkedObjectList());
1013 if( pMarkList
->GetMarkCount() == 1 )
1015 pMarkedObj
= pMarkList
->GetMark(0)->GetMarkedSdrObj();
1016 uno::Reference
< drawing::XShape
> xMarkedXShape (pMarkedObj
->getUnoShape(), uno::UNO_QUERY
);
1017 if( aFocusedItr
!= aDataEndItr
&&
1018 (*aFocusedItr
)->xShape
.is() &&
1019 xMarkedXShape
.is() &&
1020 (*aFocusedItr
)->xShape
!= xMarkedXShape
)
1021 bIsFocuseMarked
= false;
1025 //if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape.is() && (mnShapesSelected == 1))
1026 if ( bIsFocuseMarked
&& (aFocusedItr
!= aDataEndItr
) && (*aFocusedItr
)->pAccShape
.is() && (mnShapesSelected
== 1) && bWinFocus
)
1028 (*aFocusedItr
)->pAccShape
->SetState(AccessibleStateType::FOCUSED
);
1030 else if( pFocusedObj
&& bWinFocus
&& pMarkList
&& pMarkList
->GetMarkCount() == 1 && mnShapesSelected
== 1 )
1034 uno::Reference
< drawing::XShape
> xMarkedXShape (pMarkedObj
->getUnoShape(), uno::UNO_QUERY
);
1035 SdrObject
* pUpObj
= pMarkedObj
->getParentSdrObjectFromSdrObject();
1037 if( pMarkedObj
== pFocusedObj
&& pUpObj
)
1039 uno::Reference
< drawing::XShape
> xUpGroupXShape (pUpObj
->getUnoShape(), uno::UNO_QUERY
);
1040 uno::Reference
< XAccessible
> xAccGroupShape
=
1041 const_cast<ScChildrenShapes
*>(this)->GetAccessibleCaption( xUpGroupXShape
);
1042 if( xAccGroupShape
.is() )
1044 ::accessibility::AccessibleShape
* pAccGroupShape
=
1045 static_cast< ::accessibility::AccessibleShape
* >(xAccGroupShape
.get());
1046 if( pAccGroupShape
)
1048 sal_Int64 nCount
= pAccGroupShape
->getAccessibleChildCount();
1049 for( sal_Int64 i
= 0; i
< nCount
; i
++ )
1051 uno::Reference
<XAccessible
> xAccShape
= pAccGroupShape
->getAccessibleChild(i
);
1054 ::accessibility::AccessibleShape
* pChildAccShape
= static_cast< ::accessibility::AccessibleShape
* >(xAccShape
.get());
1055 uno::Reference
< drawing::XShape
> xChildShape
= pChildAccShape
->GetXShape();
1056 if (xChildShape
== xMarkedXShape
)
1058 pChildAccShape
->SetState(AccessibleStateType::FOCUSED
);
1062 pChildAccShape
->ResetState(AccessibleStateType::FOCUSED
);
1071 if (vecSelectedShapeAdd
.size() >= 10 )
1073 AccessibleEventObject aEvent
;
1074 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_WITHIN
;
1075 aEvent
.Source
= uno::Reference
< XAccessible
>(mpAccessibleDocument
);
1076 mpAccessibleDocument
->CommitChange(aEvent
);
1080 for (const auto& rpShape
: vecSelectedShapeAdd
)
1082 AccessibleEventObject aEvent
;
1085 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_ADD
;
1089 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED
;
1091 aEvent
.Source
= uno::Reference
< XAccessible
>(mpAccessibleDocument
);
1092 uno::Reference
< XAccessible
> xChild( rpShape
->pAccShape
);
1093 aEvent
.NewValue
<<= xChild
;
1094 mpAccessibleDocument
->CommitChange(aEvent
);
1097 for (const auto& rpShape
: vecSelectedShapeRemove
)
1099 AccessibleEventObject aEvent
;
1100 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED_REMOVE
;
1101 aEvent
.Source
= uno::Reference
< XAccessible
>(mpAccessibleDocument
);
1102 uno::Reference
< XAccessible
> xChild( rpShape
->pAccShape
);
1103 aEvent
.NewValue
<<= xChild
;
1104 mpAccessibleDocument
->CommitChange(aEvent
);
1106 for(ScAccessibleShapeData
*& pShapeData
: aShapesList
)
1109 pShapeData
= nullptr;
1114 std::optional
<ScAddress
> ScChildrenShapes::GetAnchor(const uno::Reference
<drawing::XShape
>& xShape
) const
1118 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape(xShape
);
1119 uno::Reference
<beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
1120 if (pSdrObj
&& xShapeProp
.is())
1122 if (ScDrawObjData
*pAnchor
= ScDrawLayer::GetObjData(pSdrObj
))
1123 return std::optional
<ScAddress
>(pAnchor
->maStart
);
1127 return std::optional
<ScAddress
>();
1130 rtl::Reference
<utl::AccessibleRelationSetHelper
> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData
* pData
) const
1132 rtl::Reference
<utl::AccessibleRelationSetHelper
> pRelationSet
= new utl::AccessibleRelationSetHelper();
1134 if (pData
&& mpAccessibleDocument
)
1136 uno::Reference
<XAccessible
> xAccessible
= mpAccessibleDocument
->GetAccessibleSpreadsheet(); // should be the current table
1137 if (pData
->xRelationCell
&& xAccessible
.is())
1139 sal_Int32 nRow
= pData
->xRelationCell
->Row();
1140 sal_Int32 nColumn
= pData
->xRelationCell
->Col();
1141 bool bPositionUnset
= nRow
== -1 && nColumn
== -1;
1142 if (!bPositionUnset
)
1144 uno::Reference
<XAccessibleTable
> xAccTable(xAccessible
->getAccessibleContext(), uno::UNO_QUERY
);
1146 xAccessible
= xAccTable
->getAccessibleCellAt(nRow
, nColumn
);
1149 AccessibleRelation aRelation
;
1150 aRelation
.TargetSet
= { xAccessible
};
1151 aRelation
.RelationType
= AccessibleRelationType_CONTROLLED_BY
;
1152 pRelationSet
->AddRelation(aRelation
);
1155 return pRelationSet
;
1158 void ScChildrenShapes::SetAnchor(const uno::Reference
<drawing::XShape
>& xShape
, ScAccessibleShapeData
* pData
) const
1162 std::optional
<ScAddress
> xAddress
= GetAnchor(xShape
);
1163 if ((xAddress
&& pData
->xRelationCell
&& (*xAddress
!= *(pData
->xRelationCell
))) ||
1164 (!xAddress
&& pData
->xRelationCell
) || (xAddress
&& !pData
->xRelationCell
))
1166 pData
->xRelationCell
= std::move(xAddress
);
1167 if (pData
->pAccShape
.is())
1168 pData
->pAccShape
->SetRelationSet(GetRelationSet(pData
));
1173 void ScChildrenShapes::AddShape(const uno::Reference
<drawing::XShape
>& xShape
, bool bCommitChange
) const
1175 assert( maShapesMap
.find(xShape
) == maShapesMap
.end());
1177 ScAccessibleShapeData
* pShape
= new ScAccessibleShapeData(xShape
);
1178 maZOrderedShapes
.push_back(pShape
);
1179 mbShapesNeedSorting
= true;
1180 maShapesMap
[xShape
] = pShape
;
1181 SetAnchor(xShape
, pShape
);
1183 uno::Reference
< beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
1184 if (xShapeProp
.is())
1186 uno::Any aPropAny
= xShapeProp
->getPropertyValue(u
"LayerID"_ustr
);
1187 sal_Int16 nLayerID
= 0;
1188 if( aPropAny
>>= nLayerID
)
1190 if( (SdrLayerID(nLayerID
) == SC_LAYER_INTERN
) || (SdrLayerID(nLayerID
) == SC_LAYER_HIDDEN
) )
1191 pShape
->bSelectable
= false;
1193 pShape
->bSelectable
= true;
1197 if (!xSelectionSupplier
.is())
1198 throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::AddShape.");
1200 uno::Reference
<drawing::XShapes
> xShapes(mpViewShell
->getSelectedXShapes());
1201 uno::Reference
<container::XEnumerationAccess
> xEnumAcc(xShapes
, uno::UNO_QUERY
);
1204 uno::Reference
<container::XEnumeration
> xEnum
= xEnumAcc
->createEnumeration();
1207 uno::Reference
<drawing::XShape
> xSelectedShape
;
1209 while (!bFound
&& xEnum
->hasMoreElements())
1211 xEnum
->nextElement() >>= xSelectedShape
;
1212 if (xShape
.is() && (xShape
.get() == xSelectedShape
.get()))
1214 pShape
->bSelected
= true;
1220 if (mpAccessibleDocument
&& bCommitChange
)
1222 AccessibleEventObject aEvent
;
1223 aEvent
.EventId
= AccessibleEventId::CHILD
;
1224 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
1225 aEvent
.NewValue
<<= Get(pShape
);
1226 aEvent
.IndexHint
= -1;
1228 mpAccessibleDocument
->CommitChange(aEvent
); // new child - event
1232 void ScChildrenShapes::RemoveShape(const uno::Reference
<drawing::XShape
>& xShape
) const
1234 if (mbShapesNeedSorting
)
1236 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
1237 mbShapesNeedSorting
= false;
1239 SortedShapes::iterator aItr
;
1240 if (FindShape(xShape
, aItr
))
1242 if (mpAccessibleDocument
)
1244 uno::Reference
<XAccessible
> xOldAccessible (Get(*aItr
));
1247 maShapesMap
.erase((*aItr
)->xShape
);
1248 maZOrderedShapes
.erase(aItr
);
1250 AccessibleEventObject aEvent
;
1251 aEvent
.EventId
= AccessibleEventId::CHILD
;
1252 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccessibleDocument
);
1253 aEvent
.OldValue
<<= xOldAccessible
;
1254 aEvent
.IndexHint
= -1;
1256 mpAccessibleDocument
->CommitChange(aEvent
); // child is gone - event
1261 maShapesMap
.erase((*aItr
)->xShape
);
1262 maZOrderedShapes
.erase(aItr
);
1267 OSL_FAIL("shape was not in internal list");
1271 bool ScChildrenShapes::FindShape(const uno::Reference
<drawing::XShape
>& xShape
, ScChildrenShapes::SortedShapes::iterator
& rItr
) const
1273 if (mbShapesNeedSorting
)
1275 std::sort(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), ScShapeDataLess());
1276 mbShapesNeedSorting
= false;
1278 bool bResult(false);
1279 ScAccessibleShapeData
aShape(xShape
);
1280 rItr
= std::lower_bound(maZOrderedShapes
.begin(), maZOrderedShapes
.end(), &aShape
, ScShapeDataLess());
1281 if ((rItr
!= maZOrderedShapes
.end()) && (*rItr
!= nullptr) && ((*rItr
)->xShape
.get() == xShape
.get()))
1282 bResult
= true; // if the shape is found
1284 #if OSL_DEBUG_LEVEL > 0 // test whether it finds truly the correct shape (perhaps it is not really sorted)
1285 SortedShapes::iterator aDebugItr
= std::find_if(maZOrderedShapes
.begin(), maZOrderedShapes
.end(),
1286 [&xShape
](const ScAccessibleShapeData
* pShape
) { return pShape
&& (pShape
->xShape
.get() == xShape
.get()); });
1287 bool bResult2
= (aDebugItr
!= maZOrderedShapes
.end());
1288 OSL_ENSURE((bResult
== bResult2
) && ((bResult
&& (rItr
== aDebugItr
)) || !bResult
), "wrong Shape found");
1293 sal_Int8
ScChildrenShapes::Compare(const ScAccessibleShapeData
* pData1
,
1294 const ScAccessibleShapeData
* pData2
)
1296 ScShapeDataLess aLess
;
1298 bool bResult1(aLess(pData1
, pData2
));
1299 bool bResult2(aLess(pData2
, pData1
));
1301 sal_Int8
nResult(0);
1302 if (!bResult1
&& bResult2
)
1304 else if (bResult1
&& !bResult2
)
1310 void ScChildrenShapes::VisAreaChanged() const
1312 for (const ScAccessibleShapeData
* pAccShapeData
: maZOrderedShapes
)
1313 if (pAccShapeData
&& pAccShapeData
->pAccShape
.is())
1314 pAccShapeData
->pAccShape
->ViewForwarderChanged();
1317 ScAccessibleDocument::ScAccessibleDocument(
1318 const uno::Reference
<XAccessible
>& rxParent
,
1319 ScTabViewShell
* pViewShell
,
1320 ScSplitPos eSplitPos
)
1321 : ScAccessibleDocumentBase(rxParent
),
1322 mpViewShell(pViewShell
),
1323 meSplitPos(eSplitPos
),
1324 mbCompleteSheetSelected(false)
1326 maVisArea
= GetVisibleArea_Impl();
1329 void ScAccessibleDocument::PreInit()
1334 mpViewShell
->AddAccessibilityObject(*this);
1335 vcl::Window
*pWin
= mpViewShell
->GetWindowByPos(meSplitPos
);
1338 pWin
->AddChildEventListener( LINK( this, ScAccessibleDocument
, WindowChildEventListener
));
1339 sal_uInt16 nCount
= pWin
->GetChildCount();
1340 for( sal_uInt16 i
=0; i
< nCount
; ++i
)
1342 vcl::Window
*pChildWin
= pWin
->GetChild( i
);
1344 AccessibleRole::EMBEDDED_OBJECT
== pChildWin
->GetAccessibleRole() )
1345 AddChild( pChildWin
->GetAccessible(), false );
1348 ScViewData
& rViewData
= mpViewShell
->GetViewData();
1349 if (rViewData
.HasEditView(meSplitPos
))
1351 uno::Reference
<XAccessible
> xAcc
= new ScAccessibleEditObject(this, rViewData
.GetEditView(meSplitPos
),
1352 mpViewShell
->GetWindowByPos(meSplitPos
), GetCurrentCellName(), GetCurrentCellDescription(),
1353 ScAccessibleEditObject::CellInEditMode
);
1354 AddChild(xAcc
, false);
1358 void ScAccessibleDocument::Init()
1360 if(!mpChildrenShapes
)
1361 mpChildrenShapes
.reset( new ScChildrenShapes(this, mpViewShell
, meSplitPos
) );
1364 ScAccessibleDocument::~ScAccessibleDocument()
1366 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper
.bInDispose
)
1368 // increment refcount to prevent double call off dtor
1369 osl_atomic_increment( &m_refCount
);
1374 void SAL_CALL
ScAccessibleDocument::disposing()
1376 SolarMutexGuard aGuard
;
1377 FreeAccessibleSpreadsheet();
1380 vcl::Window
*pWin
= mpViewShell
->GetWindowByPos(meSplitPos
);
1382 pWin
->RemoveChildEventListener( LINK( this, ScAccessibleDocument
, WindowChildEventListener
));
1384 mpViewShell
->RemoveAccessibilityObject(*this);
1385 mpViewShell
= nullptr;
1387 mpChildrenShapes
.reset();
1389 ScAccessibleDocumentBase::disposing();
1392 void SAL_CALL
ScAccessibleDocument::disposing( const lang::EventObject
& /* Source */ )
1397 //===== SfxListener =====================================================
1399 IMPL_LINK( ScAccessibleDocument
, WindowChildEventListener
, VclWindowEvent
&, rEvent
, void )
1401 OSL_ENSURE( rEvent
.GetWindow(), "Window???" );
1402 switch ( rEvent
.GetId() )
1404 case VclEventId::WindowShow
: // send create on show for direct accessible children
1406 vcl::Window
* pChildWin
= static_cast < vcl::Window
* >( rEvent
.GetData() );
1407 if( pChildWin
&& AccessibleRole::EMBEDDED_OBJECT
== pChildWin
->GetAccessibleRole() )
1409 AddChild( pChildWin
->GetAccessible(), true );
1413 case VclEventId::WindowHide
: // send destroy on hide for direct accessible children
1415 vcl::Window
* pChildWin
= static_cast < vcl::Window
* >( rEvent
.GetData() );
1416 if( pChildWin
&& AccessibleRole::EMBEDDED_OBJECT
== pChildWin
->GetAccessibleRole() )
1418 RemoveChild( pChildWin
->GetAccessible(), true );
1426 void ScAccessibleDocument::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1428 if (rHint
.GetId() == SfxHintId::ScAccGridWinFocusLost
)
1430 auto pFocusLostHint
= static_cast<const ScAccGridWinFocusLostHint
*>(&rHint
);
1431 if (pFocusLostHint
->GetOldGridWin() == meSplitPos
)
1433 if (mxTempAcc
.is() && mpTempAccEdit
)
1434 mpTempAccEdit
->LostFocus();
1435 else if (mpAccessibleSpreadsheet
.is())
1436 mpAccessibleSpreadsheet
->LostFocus();
1441 else if (rHint
.GetId() == SfxHintId::ScAccGridWinFocusGot
)
1443 auto pFocusGotHint
= static_cast<const ScAccGridWinFocusGotHint
*>(&rHint
);
1444 if (pFocusGotHint
->GetNewGridWin() == meSplitPos
)
1446 uno::Reference
<XAccessible
> xAccessible
;
1447 if (mpChildrenShapes
)
1449 bool bTabMarked(IsTableSelected());
1450 xAccessible
= mpChildrenShapes
->GetSelected(0, bTabMarked
);
1452 if( xAccessible
.is() )
1455 aNewValue
<<=AccessibleStateType::FOCUSED
;
1456 static_cast< ::accessibility::AccessibleShape
* >(xAccessible
.get())->
1457 CommitChange(AccessibleEventId::STATE_CHANGED
,
1463 if (mxTempAcc
.is() && mpTempAccEdit
)
1464 mpTempAccEdit
->GotFocus();
1465 else if (mpAccessibleSpreadsheet
.is())
1466 mpAccessibleSpreadsheet
->GotFocus();
1468 CommitFocusGained();
1472 else if (rHint
.GetId() == SfxHintId::ScAccTableChanged
)
1474 // only notify if child exist, otherwise it is not necessary
1475 if (mpAccessibleSpreadsheet
.is())
1477 FreeAccessibleSpreadsheet();
1479 // Shapes / form controls after reload not accessible, rebuild the
1480 // mpChildrenShapes variable.
1481 mpChildrenShapes
.reset( new ScChildrenShapes( this, mpViewShell
, meSplitPos
) );
1483 AccessibleEventObject aEvent
;
1484 aEvent
.EventId
= AccessibleEventId::INVALIDATE_ALL_CHILDREN
;
1485 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1486 CommitChange(aEvent
); // all children changed
1488 if (mpAccessibleSpreadsheet
.is())
1489 mpAccessibleSpreadsheet
->GotFocus();
1492 else if (rHint
.GetId() == SfxHintId::ScAccMakeDrawLayer
)
1494 if (mpChildrenShapes
)
1495 mpChildrenShapes
->SetDrawBroadcaster();
1497 else if (rHint
.GetId() == SfxHintId::ScAccEnterEditMode
) // this event comes only on creating edit field of a cell
1499 if (mpViewShell
->GetViewData().GetEditActivePart() == meSplitPos
)
1501 ScViewData
& rViewData
= mpViewShell
->GetViewData();
1502 EditEngine
const& rEditEng
= rViewData
.GetEditView(meSplitPos
)->getEditEngine();
1503 if (rEditEng
.IsUpdateLayout())
1505 mpTempAccEdit
= new ScAccessibleEditObject(this, rViewData
.GetEditView(meSplitPos
),
1506 mpViewShell
->GetWindowByPos(meSplitPos
), GetCurrentCellName(),
1507 ScResId(STR_ACC_EDITLINE_DESCR
), ScAccessibleEditObject::CellInEditMode
);
1508 uno::Reference
<XAccessible
> xAcc
= mpTempAccEdit
;
1510 AddChild(xAcc
, true);
1512 if (mpAccessibleSpreadsheet
.is())
1513 mpAccessibleSpreadsheet
->LostFocus();
1517 mpTempAccEdit
->GotFocus();
1521 else if (rHint
.GetId() == SfxHintId::ScAccLeaveEditMode
)
1527 mpTempAccEdit
->LostFocus();
1529 RemoveChild(mxTempAcc
, true);
1532 // tdf#125982 a11y use-after-free of editengine by
1533 // ScAccessibleEditObjectTextData living past the
1534 // the editengine of the editview passed in above
1535 // in ScAccEnterEditMode
1536 mpTempAccEdit
->dispose();
1537 mpTempAccEdit
= nullptr;
1539 if (mpAccessibleSpreadsheet
.is() && mpViewShell
&& mpViewShell
->IsActive())
1540 mpAccessibleSpreadsheet
->GotFocus();
1541 else if( mpViewShell
&& mpViewShell
->IsActive())
1542 CommitFocusGained();
1545 else if ((rHint
.GetId() == SfxHintId::ScAccVisAreaChanged
) || (rHint
.GetId() == SfxHintId::ScAccWindowResized
))
1547 tools::Rectangle
aOldVisArea(maVisArea
);
1548 maVisArea
= GetVisibleArea_Impl();
1550 if (maVisArea
!= aOldVisArea
)
1552 if (maVisArea
.GetSize() != aOldVisArea
.GetSize())
1554 AccessibleEventObject aEvent
;
1555 aEvent
.EventId
= AccessibleEventId::BOUNDRECT_CHANGED
;
1556 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1558 CommitChange(aEvent
);
1560 if (mpAccessibleSpreadsheet
.is())
1561 mpAccessibleSpreadsheet
->BoundingBoxChanged();
1562 if (mpAccessibleSpreadsheet
.is() && mpViewShell
&& mpViewShell
->IsActive())
1563 mpAccessibleSpreadsheet
->FireFirstCellFocus();
1565 else if (mpAccessibleSpreadsheet
.is())
1567 mpAccessibleSpreadsheet
->VisAreaChanged();
1569 if (mpChildrenShapes
)
1570 mpChildrenShapes
->VisAreaChanged();
1574 ScAccessibleDocumentBase::Notify(rBC
, rHint
);
1577 void SAL_CALL
ScAccessibleDocument::selectionChanged( const lang::EventObject
& /* aEvent */ )
1579 bool bSelectionChanged(false);
1580 if (mpAccessibleSpreadsheet
.is())
1582 bool bOldSelected(mbCompleteSheetSelected
);
1583 mbCompleteSheetSelected
= IsTableSelected();
1584 if (bOldSelected
!= mbCompleteSheetSelected
)
1586 mpAccessibleSpreadsheet
->CompleteSelectionChanged(mbCompleteSheetSelected
);
1587 bSelectionChanged
= true;
1591 if (mpChildrenShapes
&& mpChildrenShapes
->SelectionChanged())
1592 bSelectionChanged
= true;
1594 if (bSelectionChanged
)
1596 AccessibleEventObject aEvent
;
1597 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED
;
1598 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1600 CommitChange(aEvent
);
1604 //===== XInterface =====================================================
1606 uno::Any SAL_CALL
ScAccessibleDocument::queryInterface( uno::Type
const & rType
)
1608 uno::Any
aAny (ScAccessibleDocumentImpl::queryInterface(rType
));
1609 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
1612 void SAL_CALL
ScAccessibleDocument::acquire()
1615 ScAccessibleContextBase::acquire();
1618 void SAL_CALL
ScAccessibleDocument::release()
1621 ScAccessibleContextBase::release();
1624 //===== XAccessibleComponent ============================================
1626 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDocument::getAccessibleAtPoint(
1627 const awt::Point
& rPoint
)
1629 uno::Reference
<XAccessible
> xAccessible
;
1630 if (containsPoint(rPoint
))
1632 SolarMutexGuard aGuard
;
1634 if (mpChildrenShapes
)
1635 xAccessible
= mpChildrenShapes
->GetAt(rPoint
);
1636 if(!xAccessible
.is())
1640 uno::Reference
< XAccessibleContext
> xCont(mxTempAcc
->getAccessibleContext());
1641 uno::Reference
< XAccessibleComponent
> xComp(xCont
, uno::UNO_QUERY
);
1644 tools::Rectangle
aBound(vcl::unohelper::ConvertToVCLRect(xComp
->getBounds()));
1645 if (aBound
.Contains(vcl::unohelper::ConvertToVCLPoint(rPoint
)))
1646 xAccessible
= mxTempAcc
;
1649 if (!xAccessible
.is())
1650 xAccessible
= GetAccessibleSpreadsheet();
1656 void SAL_CALL
ScAccessibleDocument::grabFocus( )
1658 SolarMutexGuard aGuard
;
1660 if (!getAccessibleParent().is())
1663 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
1664 if (xAccessibleComponent
.is())
1666 xAccessibleComponent
->grabFocus();
1667 // grab only focus if it does not have the focus and it is not hidden
1669 (mpViewShell
->GetViewData().GetActivePart() != meSplitPos
) &&
1670 mpViewShell
->GetWindowByPos(meSplitPos
)->IsVisible())
1672 mpViewShell
->ActivatePart(meSplitPos
);
1677 //===== XAccessibleContext ==============================================
1679 /// Return the number of currently visible children.
1681 ScAccessibleDocument::getAccessibleChildCount()
1683 SolarMutexGuard aGuard
;
1685 sal_Int64
nCount(1);
1686 if (mpChildrenShapes
)
1687 nCount
= mpChildrenShapes
->GetCount(); // returns the count of the shapes inclusive the table
1695 /// Return the specified child or NULL if index is invalid.
1696 uno::Reference
<XAccessible
> SAL_CALL
1697 ScAccessibleDocument::getAccessibleChild(sal_Int64 nIndex
)
1699 SolarMutexGuard aGuard
;
1701 uno::Reference
<XAccessible
> xAccessible
;
1704 sal_Int64
nCount(1);
1705 if (mpChildrenShapes
)
1707 xAccessible
= mpChildrenShapes
->Get(nIndex
); // returns NULL if it is the table or out of range
1708 nCount
= mpChildrenShapes
->GetCount(); //there is always a table
1710 if (!xAccessible
.is())
1712 if (nIndex
< nCount
)
1713 xAccessible
= GetAccessibleSpreadsheet();
1714 else if (nIndex
== nCount
&& mxTempAcc
.is())
1715 xAccessible
= mxTempAcc
;
1719 if (!xAccessible
.is())
1720 throw lang::IndexOutOfBoundsException();
1725 /// Return the set of current states.
1727 ScAccessibleDocument::getAccessibleStateSet()
1729 SolarMutexGuard aGuard
;
1730 sal_Int64 nParentStates
= 0;
1731 if (getAccessibleParent().is())
1733 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
1734 nParentStates
= xParentContext
->getAccessibleStateSet();
1736 sal_Int64 nStateSet
= 0;
1737 if (IsDefunc(nParentStates
))
1738 nStateSet
|= AccessibleStateType::DEFUNC
;
1741 nStateSet
|= AccessibleStateType::EDITABLE
;
1742 nStateSet
|= AccessibleStateType::ENABLED
;
1743 nStateSet
|= AccessibleStateType::OPAQUE
;
1745 nStateSet
|= AccessibleStateType::SHOWING
;
1747 nStateSet
|= AccessibleStateType::VISIBLE
;
1753 ScAccessibleDocument::getAccessibleName()
1757 OUString aName
= ScResId(STR_ACC_DOC_SPREADSHEET
);
1758 ScDocument
* pScDoc
= GetDocument();
1762 ScDocShell
* pObjSh
= pScDoc
->GetDocumentShell();
1767 SfxMedium
* pMed
= pObjSh
->GetMedium();
1769 aFileName
= pMed
->GetName();
1771 if (aFileName
.isEmpty())
1772 aFileName
= pObjSh
->GetTitle(SFX_TITLE_APINAME
);
1774 if (!aFileName
.isEmpty())
1777 if (pObjSh
->IsReadOnly())
1778 aReadOnly
= ScResId(STR_ACC_DOC_SPREADSHEET_READONLY
);
1780 aName
= aFileName
+ aReadOnly
+ " - " + aName
;
1785 ///===== XAccessibleSelection ===========================================
1788 ScAccessibleDocument::selectAccessibleChild( sal_Int64 nChildIndex
)
1790 SolarMutexGuard aGuard
;
1793 if (!(mpChildrenShapes
&& mpViewShell
))
1796 sal_Int32
nCount(mpChildrenShapes
->GetCount()); // all shapes and the table
1799 if (nChildIndex
< 0 || nChildIndex
>= nCount
)
1800 throw lang::IndexOutOfBoundsException();
1802 uno::Reference
< XAccessible
> xAccessible
= mpChildrenShapes
->Get(nChildIndex
);
1803 if (xAccessible
.is())
1805 bool bWasTableSelected(IsTableSelected());
1806 mpChildrenShapes
->Select(nChildIndex
); // throws no lang::IndexOutOfBoundsException if Index is too high
1807 if (bWasTableSelected
)
1808 mpViewShell
->SelectAll();
1812 mpViewShell
->SelectAll();
1817 ScAccessibleDocument::isAccessibleChildSelected( sal_Int64 nChildIndex
)
1819 SolarMutexGuard aGuard
;
1821 bool bResult(false);
1823 if (mpChildrenShapes
)
1825 sal_Int32
nCount(mpChildrenShapes
->GetCount()); // all shapes and the table
1828 if (nChildIndex
< 0 || nChildIndex
>= nCount
)
1829 throw lang::IndexOutOfBoundsException();
1831 uno::Reference
< XAccessible
> xAccessible
= mpChildrenShapes
->Get(nChildIndex
);
1832 if (xAccessible
.is())
1834 uno::Reference
<drawing::XShape
> xShape
;
1835 bResult
= mpChildrenShapes
->IsSelected(nChildIndex
, xShape
); // throws no lang::IndexOutOfBoundsException if Index is too high
1839 if (mxTempAcc
.is() && nChildIndex
== nCount
)
1842 bResult
= IsTableSelected();
1849 ScAccessibleDocument::clearAccessibleSelection( )
1851 SolarMutexGuard aGuard
;
1854 if (mpChildrenShapes
)
1855 mpChildrenShapes
->DeselectAll(); //deselects all (also the table)
1859 ScAccessibleDocument::selectAllAccessibleChildren( )
1861 SolarMutexGuard aGuard
;
1864 if (mpChildrenShapes
)
1865 mpChildrenShapes
->SelectAll();
1867 // select table after shapes, because while selecting shapes the table will be deselected
1870 mpViewShell
->SelectAll();
1875 ScAccessibleDocument::getSelectedAccessibleChildCount( )
1877 SolarMutexGuard aGuard
;
1879 sal_Int64
nCount(0);
1881 if (mpChildrenShapes
)
1882 nCount
= mpChildrenShapes
->GetSelectedCount();
1884 if (IsTableSelected())
1893 uno::Reference
<XAccessible
> SAL_CALL
1894 ScAccessibleDocument::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex
)
1896 SolarMutexGuard aGuard
;
1898 uno::Reference
<XAccessible
> xAccessible
;
1899 if (mpChildrenShapes
)
1901 sal_Int64
nCount(getSelectedAccessibleChildCount()); //all shapes and the table
1902 if (nSelectedChildIndex
< 0 || nSelectedChildIndex
>= nCount
)
1903 throw lang::IndexOutOfBoundsException();
1905 bool bTabMarked(IsTableSelected());
1907 if (mpChildrenShapes
)
1908 xAccessible
= mpChildrenShapes
->GetSelected(nSelectedChildIndex
, bTabMarked
); // throws no lang::IndexOutOfBoundsException if Index is too high
1909 if (mxTempAcc
.is() && nSelectedChildIndex
== nCount
- 1)
1910 xAccessible
= mxTempAcc
;
1911 else if (bTabMarked
)
1912 xAccessible
= GetAccessibleSpreadsheet();
1915 OSL_ENSURE(xAccessible
.is(), "here should always be an accessible object or an exception thrown");
1921 ScAccessibleDocument::deselectAccessibleChild( sal_Int64 nChildIndex
)
1923 SolarMutexGuard aGuard
;
1926 if (!(mpChildrenShapes
&& mpViewShell
))
1929 sal_Int32
nCount(mpChildrenShapes
->GetCount()); // all shapes and the table
1932 if (nChildIndex
< 0 || nChildIndex
>= nCount
)
1933 throw lang::IndexOutOfBoundsException();
1935 bool bTabMarked(IsTableSelected());
1937 uno::Reference
< XAccessible
> xAccessible
= mpChildrenShapes
->Get(nChildIndex
);
1938 if (xAccessible
.is())
1940 mpChildrenShapes
->Deselect(nChildIndex
); // throws no lang::IndexOutOfBoundsException if Index is too high
1942 mpViewShell
->SelectAll(); // select the table again
1944 else if (bTabMarked
)
1945 mpViewShell
->Unmark();
1948 //===== XServiceInfo ====================================================
1951 ScAccessibleDocument::getImplementationName()
1953 return u
"ScAccessibleDocument"_ustr
;
1956 uno::Sequence
< OUString
> SAL_CALL
1957 ScAccessibleDocument::getSupportedServiceNames()
1959 const css::uno::Sequence
<OUString
> vals
{ u
"com.sun.star.AccessibleSpreadsheetDocumentView"_ustr
};
1960 return comphelper::concatSequences(ScAccessibleContextBase::getSupportedServiceNames(), vals
);
1963 //===== XTypeProvider =======================================================
1965 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessibleDocument::getTypes()
1967 return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
1970 uno::Sequence
<sal_Int8
> SAL_CALL
1971 ScAccessibleDocument::getImplementationId()
1973 return css::uno::Sequence
<sal_Int8
>();
1976 ///===== IAccessibleViewForwarder ========================================
1978 tools::Rectangle
ScAccessibleDocument::GetVisibleArea_Impl() const
1980 tools::Rectangle
aVisRect(GetBoundingBox());
1984 Point
aPoint(mpViewShell
->GetViewData().GetPixPos(meSplitPos
)); // returns a negative Point
1985 aPoint
.setX(-aPoint
.getX());
1986 aPoint
.setY(-aPoint
.getY());
1987 aVisRect
.SetPos(aPoint
);
1989 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
1991 aVisRect
= pWin
->PixelToLogic(aVisRect
, pWin
->GetDrawMapMode());
1997 tools::Rectangle
ScAccessibleDocument::GetVisibleArea() const
1999 SolarMutexGuard aGuard
;
2004 Point
ScAccessibleDocument::LogicToPixel (const Point
& rPoint
) const
2006 SolarMutexGuard aGuard
;
2009 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
2012 aPoint
= pWin
->LogicToPixel(rPoint
, pWin
->GetDrawMapMode());
2013 aPoint
+= Point(pWin
->GetWindowExtentsAbsolute().TopLeft());
2018 Size
ScAccessibleDocument::LogicToPixel (const Size
& rSize
) const
2020 SolarMutexGuard aGuard
;
2023 ScGridWindow
* pWin
= static_cast<ScGridWindow
*>(mpViewShell
->GetWindowByPos(meSplitPos
));
2025 aSize
= pWin
->LogicToPixel(rSize
, pWin
->GetDrawMapMode());
2029 //===== internal ========================================================
2031 rtl::Reference
<utl::AccessibleRelationSetHelper
> ScAccessibleDocument::GetRelationSet(const ScAddress
* pAddress
) const
2033 rtl::Reference
<utl::AccessibleRelationSetHelper
> pRelationSet
;
2034 if (mpChildrenShapes
)
2035 pRelationSet
= mpChildrenShapes
->GetRelationSet(pAddress
);
2036 return pRelationSet
;
2040 ScAccessibleDocument::createAccessibleDescription()
2042 return STR_ACC_DOC_DESCR
;
2046 ScAccessibleDocument::createAccessibleName()
2048 SolarMutexGuard aGuard
;
2050 OUString sName
= ScResId(STR_ACC_DOC_NAME
);
2051 sal_Int32
nNumber(sal_Int32(meSplitPos
) + 1);
2052 sName
+= OUString::number(nNumber
);
2056 AbsoluteScreenPixelRectangle
ScAccessibleDocument::GetBoundingBoxOnScreen() const
2058 AbsoluteScreenPixelRectangle aRect
;
2061 vcl::Window
* pWindow
= mpViewShell
->GetWindowByPos(meSplitPos
);
2063 aRect
= pWindow
->GetWindowExtentsAbsolute();
2068 tools::Rectangle
ScAccessibleDocument::GetBoundingBox() const
2070 tools::Rectangle aRect
;
2073 vcl::Window
* pWindow
= mpViewShell
->GetWindowByPos(meSplitPos
);
2075 aRect
= pWindow
->GetWindowExtentsRelative(*pWindow
->GetAccessibleParentWindow());
2080 SCTAB
ScAccessibleDocument::getVisibleTable() const
2082 SCTAB
nVisibleTable(0);
2084 nVisibleTable
= mpViewShell
->GetViewData().GetTabNo();
2085 return nVisibleTable
;
2088 uno::Reference
< XAccessible
>
2089 ScAccessibleDocument::GetAccessibleSpreadsheet()
2091 if (!mpAccessibleSpreadsheet
.is() && mpViewShell
)
2093 mpAccessibleSpreadsheet
= new ScAccessibleSpreadsheet(this, mpViewShell
, getVisibleTable(), meSplitPos
);
2094 mpAccessibleSpreadsheet
->Init();
2095 mbCompleteSheetSelected
= IsTableSelected();
2097 return mpAccessibleSpreadsheet
;
2100 void ScAccessibleDocument::FreeAccessibleSpreadsheet()
2102 if (mpAccessibleSpreadsheet
.is())
2104 mpAccessibleSpreadsheet
->dispose();
2105 mpAccessibleSpreadsheet
.clear();
2109 bool ScAccessibleDocument::IsTableSelected() const
2111 bool bResult (false);
2114 SCTAB
nTab(getVisibleTable());
2115 //#103800#; use a copy of MarkData
2116 ScMarkData
aMarkData(mpViewShell
->GetViewData().GetMarkData());
2117 ScDocument
* pDoc
= GetDocument();
2118 if (aMarkData
.IsAllMarked( ScRange( 0, 0, nTab
, pDoc
->MaxCol(), pDoc
->MaxRow(), nTab
)))
2124 bool ScAccessibleDocument::IsDefunc(sal_Int64 nParentStates
)
2126 return ScAccessibleContextBase::IsDefunc() || (mpViewShell
== nullptr) || !getAccessibleParent().is() ||
2127 (nParentStates
& AccessibleStateType::DEFUNC
);
2130 void ScAccessibleDocument::AddChild(const uno::Reference
<XAccessible
>& xAcc
, bool bFireEvent
)
2132 OSL_ENSURE(!mxTempAcc
.is(), "this object should be removed before");
2138 AccessibleEventObject aEvent
;
2139 aEvent
.Source
= uno::Reference
<XAccessibleContext
>(this);
2140 aEvent
.EventId
= AccessibleEventId::CHILD
;
2141 aEvent
.NewValue
<<= mxTempAcc
;
2142 aEvent
.IndexHint
= getAccessibleChildCount() - 1;
2143 CommitChange( aEvent
);
2148 void ScAccessibleDocument::RemoveChild(const uno::Reference
<XAccessible
>& xAcc
, bool bFireEvent
)
2150 OSL_ENSURE(mxTempAcc
.is(), "this object should be added before");
2154 OSL_ENSURE(xAcc
.get() == mxTempAcc
.get(), "only the same object should be removed");
2157 AccessibleEventObject aEvent
;
2158 aEvent
.Source
= uno::Reference
<XAccessibleContext
>(this);
2159 aEvent
.EventId
= AccessibleEventId::CHILD
;
2160 aEvent
.OldValue
<<= mxTempAcc
;
2161 aEvent
.IndexHint
= -1;
2162 CommitChange( aEvent
);
2164 mxTempAcc
= nullptr;
2167 OUString
ScAccessibleDocument::GetCurrentCellName() const
2169 OUString
sName(ScResId(STR_ACC_CELL_NAME
));
2172 // Document not needed, because only the cell address, but not the tablename is needed
2173 OUString
sAddress(mpViewShell
->GetViewData().GetCurPos().Format(ScRefFlags::VALID
));
2174 sName
= sName
.replaceFirst("%1", sAddress
);
2179 const OUString
& ScAccessibleDocument::GetCurrentCellDescription()
2181 return EMPTY_OUSTRING
;
2184 ScDocument
*ScAccessibleDocument::GetDocument() const
2186 return mpViewShell
? &mpViewShell
->GetViewData().GetDocument() : nullptr;
2189 ScAddress
ScAccessibleDocument::GetCurCellAddress() const
2191 return mpViewShell
? mpViewShell
->GetViewData().GetCurPos() : ScAddress();
2194 uno::Any SAL_CALL
ScAccessibleDocument::getExtendedAttributes()
2198 uno::Any anyAttribute
;
2200 sal_uInt16 sheetIndex
;
2201 OUString sSheetName
;
2202 sheetIndex
= getVisibleTable();
2203 if(GetDocument()==nullptr)
2204 return anyAttribute
;
2205 GetDocument()->GetName(sheetIndex
,sSheetName
);
2206 OUString sValue
= "page-name:" + sSheetName
+
2207 ";page-number:" + OUString::number(sheetIndex
+1) +
2208 ";total-pages:" + OUString::number(GetDocument()->GetTableCount()) + ";";
2209 anyAttribute
<<= sValue
;
2210 return anyAttribute
;
2213 sal_Int32 SAL_CALL
ScAccessibleDocument::getForeground( )
2215 return sal_Int32(COL_BLACK
);
2218 sal_Int32 SAL_CALL
ScAccessibleDocument::getBackground( )
2220 SolarMutexGuard aGuard
;
2222 return sal_Int32(ScModule::get()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR
).nColor
);
2225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */