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 <AccessibleDocumentPagePreview.hxx>
21 #include <AccessiblePreviewTable.hxx>
22 #include <AccessiblePageHeader.hxx>
23 #include <AccessibilityHints.hxx>
24 #include <AccessibleText.hxx>
25 #include <document.hxx>
26 #include <prevwsh.hxx>
27 #include <prevloc.hxx>
28 #include <drwlayer.hxx>
29 #include <editsrc.hxx>
30 #include <scresid.hxx>
31 #include <strings.hrc>
32 #include <strings.hxx>
33 #include <preview.hxx>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
39 #include <comphelper/sequence.hxx>
41 #include <tools/gen.hxx>
42 #include <svx/fmview.hxx>
43 #include <svx/svdpage.hxx>
44 #include <svx/svdobj.hxx>
45 #include <svx/AccessibleTextHelper.hxx>
46 #include <svx/AccessibleShape.hxx>
47 #include <svx/AccessibleShapeInfo.hxx>
48 #include <svx/IAccessibleParent.hxx>
49 #include <svx/IAccessibleViewForwarder.hxx>
50 #include <svx/ShapeTypeHandler.hxx>
51 #include <toolkit/helper/vclunohelper.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vcl/unohelp.hxx>
54 #include <sfx2/docfile.hxx>
61 using namespace ::com::sun::star
;
62 using namespace ::com::sun::star::accessibility
;
64 typedef std::vector
< uno::Reference
< XAccessible
> > ScXAccVector
;
71 tools::Rectangle maRect
;
73 ::accessibility::AccessibleTextHelper
* mpTextHelper
;
74 sal_Int32 mnParaCount
;
78 : mpTextHelper(nullptr)
90 ScNotesChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
);
92 void Init(const tools::Rectangle
& rVisRect
, sal_Int32 nOffset
);
94 sal_Int32
GetChildrenCount() const { return mnParagraphs
;}
95 uno::Reference
<XAccessible
> GetChild(sal_Int32 nIndex
) const;
96 uno::Reference
<XAccessible
> GetAt(const awt::Point
& rPoint
) const;
98 void DataChanged(const tools::Rectangle
& rVisRect
);
101 ScPreviewShell
* mpViewShell
;
102 ScAccessibleDocumentPagePreview
* mpAccDoc
;
103 typedef std::vector
<ScAccNote
> ScAccNotes
;
104 mutable ScAccNotes maNotes
;
105 mutable ScAccNotes maMarks
;
106 sal_Int32 mnParagraphs
;
109 ::accessibility::AccessibleTextHelper
* CreateTextHelper(const OUString
& rString
, const tools::Rectangle
& rVisRect
, const ScAddress
& aCellPos
, bool bMarkNote
, sal_Int32 nChildOffset
) const;
110 sal_Int32
AddNotes(const ScPreviewLocationData
& rData
, const tools::Rectangle
& rVisRect
, bool bMark
, ScAccNotes
& rNotes
);
112 static sal_Int8
CompareCell(const ScAddress
& aCell1
, const ScAddress
& aCell2
);
113 static void CollectChildren(const ScAccNote
& rNote
, ScXAccVector
& rVector
);
114 sal_Int32
CheckChanges(const ScPreviewLocationData
& rData
, const tools::Rectangle
& rVisRect
,
115 bool bMark
, ScAccNotes
& rOldNotes
, ScAccNotes
& rNewNotes
,
116 ScXAccVector
& rOldParas
, ScXAccVector
& rNewParas
);
118 inline ScDocument
* GetDocument() const;
121 ScNotesChildren::ScNotesChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
)
122 : mpViewShell(pViewShell
),
129 ScNotesChildren::~ScNotesChildren()
131 for (auto & i
: maNotes
)
134 delete i
.mpTextHelper
;
135 i
.mpTextHelper
= nullptr;
137 for (auto & i
: maMarks
)
140 delete i
.mpTextHelper
;
141 i
.mpTextHelper
= nullptr;
145 ::accessibility::AccessibleTextHelper
* ScNotesChildren::CreateTextHelper(const OUString
& rString
, const tools::Rectangle
& rVisRect
, const ScAddress
& aCellPos
, bool bMarkNote
, sal_Int32 nChildOffset
) const
147 ::accessibility::AccessibleTextHelper
* pTextHelper
= new ::accessibility::AccessibleTextHelper(std::make_unique
<ScAccessibilityEditSource
>(std::make_unique
<ScAccessibleNoteTextData
>(mpViewShell
, rString
, aCellPos
, bMarkNote
)));
148 pTextHelper
->SetEventSource(mpAccDoc
);
149 pTextHelper
->SetStartIndex(nChildOffset
);
150 pTextHelper
->SetOffset(rVisRect
.TopLeft());
155 sal_Int32
ScNotesChildren::AddNotes(const ScPreviewLocationData
& rData
, const tools::Rectangle
& rVisRect
, bool bMark
, ScAccNotes
& rNotes
)
157 sal_Int32 nCount
= rData
.GetNoteCountInRange(rVisRect
, bMark
);
159 rNotes
.reserve(nCount
);
161 sal_Int32
nParagraphs(0);
162 ScDocument
* pDoc
= GetDocument();
166 aNote
.mbMarkNote
= bMark
;
168 aNote
.mnParaCount
= 1;
169 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
171 if (rData
.GetNoteInRange(rVisRect
, nIndex
, bMark
, aNote
.maNoteCell
, aNote
.maRect
))
175 // Document not needed, because only the cell address, but not the tablename is needed
176 aNote
.maNoteText
= aNote
.maNoteCell
.Format(ScRefFlags::VALID
);
180 if( ScPostIt
* pNote
= pDoc
->GetNote( aNote
.maNoteCell
) )
181 aNote
.maNoteText
= pNote
->GetText();
182 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
183 if (aNote
.mpTextHelper
)
184 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
186 nParagraphs
+= aNote
.mnParaCount
;
187 rNotes
.push_back(aNote
);
194 void ScNotesChildren::Init(const tools::Rectangle
& rVisRect
, sal_Int32 nOffset
)
196 if (mpViewShell
&& !mnParagraphs
)
199 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
201 mnParagraphs
= AddNotes(rData
, rVisRect
, false, maMarks
);
202 mnParagraphs
+= AddNotes(rData
, rVisRect
, true, maNotes
);
211 explicit ScParaFound(sal_Int32 nIndex
) : mnIndex(nIndex
) {}
212 bool operator() (const ScAccNote
& rNote
)
215 if (rNote
.mnParaCount
> mnIndex
)
218 mnIndex
-= rNote
.mnParaCount
;
225 uno::Reference
<XAccessible
> ScNotesChildren::GetChild(sal_Int32 nIndex
) const
227 uno::Reference
<XAccessible
> xAccessible
;
229 if (nIndex
< mnParagraphs
)
231 if (nIndex
< static_cast<sal_Int32
>(maMarks
.size()))
233 ScAccNotes::iterator aEndItr
= maMarks
.end();
234 ScParaFound
aParaFound(nIndex
);
235 ScAccNotes::iterator aItr
= std::find_if(maMarks
.begin(), aEndItr
, aParaFound
);
238 OSL_ENSURE((aItr
->maNoteCell
== maMarks
[nIndex
].maNoteCell
) && (aItr
->mbMarkNote
== maMarks
[nIndex
].mbMarkNote
), "wrong note found");
239 if (!aItr
->mpTextHelper
)
240 aItr
->mpTextHelper
= CreateTextHelper(maMarks
[nIndex
].maNoteText
, maMarks
[nIndex
].maRect
, maMarks
[nIndex
].maNoteCell
, maMarks
[nIndex
].mbMarkNote
, nIndex
+ mnOffset
); // the marks are the first and every mark has only one paragraph
241 xAccessible
= aItr
->mpTextHelper
->GetChild(aParaFound
.mnIndex
+ aItr
->mpTextHelper
->GetStartIndex());
245 OSL_FAIL("wrong note found");
250 nIndex
-= maMarks
.size();
251 ScAccNotes::iterator aEndItr
= maNotes
.end();
252 ScParaFound
aParaFound(nIndex
);
253 ScAccNotes::iterator aItr
= std::find_if(maNotes
.begin(), aEndItr
, aParaFound
);
256 if (!aItr
->mpTextHelper
)
257 aItr
->mpTextHelper
= CreateTextHelper(aItr
->maNoteText
, aItr
->maRect
, aItr
->maNoteCell
, aItr
->mbMarkNote
, (nIndex
- aParaFound
.mnIndex
) + mnOffset
+ maMarks
.size());
258 xAccessible
= aItr
->mpTextHelper
->GetChild(aParaFound
.mnIndex
+ aItr
->mpTextHelper
->GetStartIndex());
270 tools::Rectangle maPoint
;
271 sal_Int32 mnParagraphs
;
272 explicit ScPointFound(const Point
& rPoint
) : maPoint(rPoint
, Size(0, 0)), mnParagraphs(0) {}
273 bool operator() (const ScAccNote
& rNote
)
276 if (maPoint
.Contains(rNote
.maRect
))
279 mnParagraphs
+= rNote
.mnParaCount
;
286 uno::Reference
<XAccessible
> ScNotesChildren::GetAt(const awt::Point
& rPoint
) const
288 uno::Reference
<XAccessible
> xAccessible
;
290 ScPointFound
aPointFound(Point(rPoint
.X
, rPoint
.Y
));
292 ScAccNotes::iterator aEndItr
= maMarks
.end();
293 ScAccNotes::iterator aItr
= std::find_if(maMarks
.begin(), aEndItr
, aPointFound
);
296 aEndItr
= maNotes
.end();
297 aItr
= std::find_if(maNotes
.begin(), aEndItr
, aPointFound
);
301 if (!aItr
->mpTextHelper
)
302 aItr
->mpTextHelper
= CreateTextHelper(aItr
->maNoteText
, aItr
->maRect
, aItr
->maNoteCell
, aItr
->mbMarkNote
, aPointFound
.mnParagraphs
+ mnOffset
);
303 xAccessible
= aItr
->mpTextHelper
->GetAt(rPoint
);
309 sal_Int8
ScNotesChildren::CompareCell(const ScAddress
& aCell1
, const ScAddress
& aCell2
)
311 OSL_ENSURE(aCell1
.Tab() == aCell2
.Tab(), "the notes should be on the same table");
313 if (aCell1
!= aCell2
)
315 if (aCell1
.Row() == aCell2
.Row())
316 nResult
= (aCell1
.Col() < aCell2
.Col()) ? -1 : 1;
318 nResult
= (aCell1
.Row() < aCell2
.Row()) ? -1 : 1;
323 void ScNotesChildren::CollectChildren(const ScAccNote
& rNote
, ScXAccVector
& rVector
)
325 if (rNote
.mpTextHelper
)
326 for (sal_Int32 i
= 0; i
< rNote
.mnParaCount
; ++i
)
327 rVector
.push_back(rNote
.mpTextHelper
->GetChild(i
+ rNote
.mpTextHelper
->GetStartIndex()));
330 sal_Int32
ScNotesChildren::CheckChanges(const ScPreviewLocationData
& rData
,
331 const tools::Rectangle
& rVisRect
, bool bMark
, ScAccNotes
& rOldNotes
,
332 ScAccNotes
& rNewNotes
, ScXAccVector
& rOldParas
, ScXAccVector
& rNewParas
)
334 sal_Int32 nCount
= rData
.GetNoteCountInRange(rVisRect
, bMark
);
336 rNewNotes
.reserve(nCount
);
338 sal_Int32
nParagraphs(0);
339 ScDocument
* pDoc
= GetDocument();
343 aNote
.mbMarkNote
= bMark
;
345 aNote
.mnParaCount
= 1;
346 ScAccNotes::iterator aItr
= rOldNotes
.begin();
347 ScAccNotes::iterator aEndItr
= rOldNotes
.end();
348 bool bAddNote(false);
349 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
351 if (rData
.GetNoteInRange(rVisRect
, nIndex
, bMark
, aNote
.maNoteCell
, aNote
.maRect
))
355 // Document not needed, because only the cell address, but not the tablename is needed
356 aNote
.maNoteText
= aNote
.maNoteCell
.Format(ScRefFlags::VALID
);
360 if( ScPostIt
* pNote
= pDoc
->GetNote( aNote
.maNoteCell
) )
361 aNote
.maNoteText
= pNote
->GetText();
364 sal_Int8
nCompare(-1); // if there are no more old children it is always a new one
366 nCompare
= CompareCell(aNote
.maNoteCell
, aItr
->maNoteCell
);
369 if (aNote
.maNoteText
== aItr
->maNoteText
)
371 aNote
.mpTextHelper
= aItr
->mpTextHelper
;
372 if (aNote
.maRect
!= aItr
->maRect
) // set new VisArea
374 aNote
.mpTextHelper
->SetOffset(aNote
.maRect
.TopLeft());
375 aNote
.mpTextHelper
->UpdateChildren();
376 //OSL_ENSURE(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
377 // could be changed, because only a part of the note is visible
382 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
383 if (aNote
.mpTextHelper
)
384 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
385 // collect removed children
386 CollectChildren(*aItr
, rOldParas
);
387 delete aItr
->mpTextHelper
;
388 aItr
->mpTextHelper
= nullptr;;
389 // collect new children
390 CollectChildren(aNote
, rNewParas
);
393 // not necessary, because this branch should not be reached if it is the end
394 //if (aItr != aEndItr)
397 else if (nCompare
< 0)
399 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
400 if (aNote
.mpTextHelper
)
401 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
402 // collect new children
403 CollectChildren(aNote
, rNewParas
);
408 // collect removed children
409 CollectChildren(*aItr
, rOldParas
);
410 delete aItr
->mpTextHelper
;
411 aItr
->mpTextHelper
= nullptr;
414 // not necessary, because this branch should not be reached if it is the end
415 //if (aItr != aEndItr)
420 nParagraphs
+= aNote
.mnParaCount
;
421 rNewNotes
.push_back(aNote
);
434 ScAccessibleDocumentPagePreview
* mpAccDoc
;
435 explicit ScChildGone(ScAccessibleDocumentPagePreview
* pAccDoc
) : mpAccDoc(pAccDoc
) {}
436 void operator() (const uno::Reference
<XAccessible
>& xAccessible
) const
440 AccessibleEventObject aEvent
;
441 aEvent
.EventId
= AccessibleEventId::CHILD
;
442 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccDoc
);
443 aEvent
.OldValue
<<= xAccessible
;
444 aEvent
.IndexHint
= -1;
446 mpAccDoc
->CommitChange(aEvent
); // gone child - event
453 ScAccessibleDocumentPagePreview
* mpAccDoc
;
454 explicit ScChildNew(ScAccessibleDocumentPagePreview
* pAccDoc
) : mpAccDoc(pAccDoc
) {}
455 void operator() (const uno::Reference
<XAccessible
>& xAccessible
) const
459 AccessibleEventObject aEvent
;
460 aEvent
.EventId
= AccessibleEventId::CHILD
;
461 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccDoc
);
462 aEvent
.NewValue
<<= xAccessible
;
463 aEvent
.IndexHint
= -1;
465 mpAccDoc
->CommitChange(aEvent
); // new child - event
472 void ScNotesChildren::DataChanged(const tools::Rectangle
& rVisRect
)
474 if (!(mpViewShell
&& mpAccDoc
))
477 ScXAccVector aNewParas
;
478 ScXAccVector aOldParas
;
480 ScAccNotes aNewMarks
;
481 mnParagraphs
= CheckChanges(mpViewShell
->GetLocationData(), rVisRect
, true, maMarks
, aNewMarks
, aOldParas
, aNewParas
);
482 maMarks
= std::move(aNewMarks
);
485 ScAccNotes aNewNotes
;
486 mnParagraphs
+= CheckChanges(mpViewShell
->GetLocationData(), rVisRect
, false, maNotes
, aNewNotes
, aOldParas
, aNewParas
);
487 maNotes
= std::move(aNewNotes
);
490 std::for_each(aOldParas
.begin(), aOldParas
.end(), ScChildGone(mpAccDoc
));
491 std::for_each(aNewParas
.begin(), aNewParas
.end(), ScChildNew(mpAccDoc
));
494 inline ScDocument
* ScNotesChildren::GetDocument() const
496 ScDocument
* pDoc
= nullptr;
498 pDoc
= &mpViewShell
->GetDocument();
504 class ScIAccessibleViewForwarder
: public ::accessibility::IAccessibleViewForwarder
507 ScIAccessibleViewForwarder();
508 ScIAccessibleViewForwarder(ScPreviewShell
* pViewShell
,
509 ScAccessibleDocumentPagePreview
* pAccDoc
,
510 const MapMode
& aMapMode
);
512 ///===== IAccessibleViewForwarder ========================================
514 virtual tools::Rectangle
GetVisibleArea() const override
;
515 virtual Point
LogicToPixel (const Point
& rPoint
) const override
;
516 virtual Size
LogicToPixel (const Size
& rSize
) const override
;
519 ScPreviewShell
* mpViewShell
;
520 ScAccessibleDocumentPagePreview
* mpAccDoc
;
526 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
527 : mpViewShell(nullptr), mpAccDoc(nullptr)
531 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell
* pViewShell
,
532 ScAccessibleDocumentPagePreview
* pAccDoc
,
533 const MapMode
& aMapMode
)
534 : mpViewShell(pViewShell
),
540 ///===== IAccessibleViewForwarder ========================================
542 tools::Rectangle
ScIAccessibleViewForwarder::GetVisibleArea() const
544 SolarMutexGuard aGuard
;
545 tools::Rectangle aVisRect
;
546 vcl::Window
* pWin
= mpViewShell
->GetWindow();
549 aVisRect
.SetSize(pWin
->GetOutputSizePixel());
550 aVisRect
.SetPos(Point(0, 0));
552 aVisRect
= pWin
->PixelToLogic(aVisRect
, maMapMode
);
558 Point
ScIAccessibleViewForwarder::LogicToPixel (const Point
& rPoint
) const
560 SolarMutexGuard aGuard
;
562 vcl::Window
* pWin
= mpViewShell
->GetWindow();
563 if (pWin
&& mpAccDoc
)
565 tools::Rectangle
aRect(mpAccDoc
->GetBoundingBoxOnScreen());
566 aPoint
= pWin
->LogicToPixel(rPoint
, maMapMode
) + aRect
.TopLeft();
572 Size
ScIAccessibleViewForwarder::LogicToPixel (const Size
& rSize
) const
574 SolarMutexGuard aGuard
;
576 vcl::Window
* pWin
= mpViewShell
->GetWindow();
578 aSize
= pWin
->LogicToPixel(rSize
, maMapMode
);
590 ScShapeChild(ScShapeChild
const &) = delete;
591 ScShapeChild(ScShapeChild
&&) = default;
593 ScShapeChild
& operator =(ScShapeChild
const &) = delete;
594 ScShapeChild
& operator =(ScShapeChild
&& other
) {
595 std::swap(mpAccShape
, other
.mpAccShape
);
596 mxShape
= std::move(other
.mxShape
);
597 mnRangeId
= other
.mnRangeId
;
601 mutable rtl::Reference
< ::accessibility::AccessibleShape
> mpAccShape
;
602 css::uno::Reference
< css::drawing::XShape
> mxShape
;
608 ScShapeChild::~ScShapeChild()
612 mpAccShape
->dispose();
618 struct ScShapeChildLess
620 bool operator()(const ScShapeChild
& rChild1
, const ScShapeChild
& rChild2
) const
623 if (rChild1
.mxShape
.is() && rChild2
.mxShape
.is())
624 bResult
= (rChild1
.mxShape
.get() < rChild2
.mxShape
.get());
631 typedef std::vector
<ScShapeChild
> ScShapeChildVec
;
637 ScShapeRange() = default;
638 ScShapeRange(ScShapeRange
const &) = delete;
639 ScShapeRange(ScShapeRange
&&) = default;
640 ScShapeRange
& operator =(ScShapeRange
const &) = delete;
641 ScShapeRange
& operator =(ScShapeRange
&&) = default;
643 ScShapeChildVec maBackShapes
;
644 ScShapeChildVec maForeShapes
; // inclusive internal shapes
645 ScShapeChildVec maControls
;
646 ScIAccessibleViewForwarder maViewForwarder
;
651 typedef std::vector
<ScShapeRange
> ScShapeRangeVec
;
653 class ScShapeChildren
: public ::accessibility::IAccessibleParent
656 ScShapeChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
);
658 ///===== IAccessibleParent ==============================================
660 virtual bool ReplaceChild (
661 ::accessibility::AccessibleShape
* pCurrentChild
,
662 const css::uno::Reference
< css::drawing::XShape
>& _rxShape
,
663 const tools::Long _nIndex
,
664 const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
667 ///===== Internal ========================================================
671 sal_Int32
GetBackShapeCount() const;
672 uno::Reference
<XAccessible
> GetBackShape(sal_Int32 nIndex
) const;
673 sal_Int32
GetForeShapeCount() const;
674 uno::Reference
<XAccessible
> GetForeShape(sal_Int32 nIndex
) const;
675 sal_Int32
GetControlCount() const;
676 uno::Reference
<XAccessible
> GetControl(sal_Int32 nIndex
) const;
677 uno::Reference
<XAccessible
> GetForegroundShapeAt(const awt::Point
& rPoint
) const; // inclusive controls
678 uno::Reference
<XAccessible
> GetBackgroundShapeAt(const awt::Point
& rPoint
) const;
681 void VisAreaChanged() const;
684 ScAccessibleDocumentPagePreview
* mpAccDoc
;
685 ScPreviewShell
* mpViewShell
;
686 ScShapeRangeVec maShapeRanges
;
688 void FindChanged(ScShapeChildVec
& aOld
, ScShapeChildVec
& aNew
) const;
689 void FindChanged(ScShapeRange
& aOld
, ScShapeRange
& aNew
) const;
690 ::accessibility::AccessibleShape
* GetAccShape(const ScShapeChild
& rShape
) const;
691 ::accessibility::AccessibleShape
* GetAccShape(const ScShapeChildVec
& rShapes
, sal_Int32 nIndex
) const;
692 void FillShapes(const tools::Rectangle
& aPixelPaintRect
, const MapMode
& aMapMode
, sal_uInt8 nRangeId
);
694 // void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
695 // void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
696 SdrPage
* GetDrawPage() const;
699 ScShapeChildren::ScShapeChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
)
702 mpViewShell(pViewShell
),
703 maShapeRanges(SC_PREVIEW_MAXRANGES
)
707 void ScShapeChildren::FindChanged(ScShapeChildVec
& rOld
, ScShapeChildVec
& rNew
) const
709 ScShapeChildVec::iterator aOldItr
= rOld
.begin();
710 ScShapeChildVec::iterator aOldEnd
= rOld
.end();
711 ScShapeChildVec::const_iterator aNewItr
= rNew
.begin();
712 ScShapeChildVec::const_iterator aNewEnd
= rNew
.end();
713 uno::Reference
<XAccessible
> xAcc
;
714 while ((aNewItr
!= aNewEnd
) && (aOldItr
!= aOldEnd
))
716 if (aNewItr
->mxShape
.get() == aOldItr
->mxShape
.get())
721 else if (aNewItr
->mxShape
.get() < aOldItr
->mxShape
.get())
723 xAcc
= GetAccShape(*aNewItr
);
724 AccessibleEventObject aEvent
;
725 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
726 aEvent
.EventId
= AccessibleEventId::CHILD
;
727 aEvent
.NewValue
<<= xAcc
;
728 aEvent
.IndexHint
= -1;
729 mpAccDoc
->CommitChange(aEvent
);
734 xAcc
= GetAccShape(*aOldItr
);
735 AccessibleEventObject aEvent
;
736 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
737 aEvent
.EventId
= AccessibleEventId::CHILD
;
738 aEvent
.OldValue
<<= xAcc
;
739 aEvent
.IndexHint
= -1;
740 mpAccDoc
->CommitChange(aEvent
);
744 while (aOldItr
!= aOldEnd
)
746 xAcc
= GetAccShape(*aOldItr
);
747 AccessibleEventObject aEvent
;
748 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
749 aEvent
.EventId
= AccessibleEventId::CHILD
;
750 aEvent
.OldValue
<<= xAcc
;
751 aEvent
.IndexHint
= -1;
752 mpAccDoc
->CommitChange(aEvent
);
755 while (aNewItr
!= aNewEnd
)
757 xAcc
= GetAccShape(*aNewItr
);
758 AccessibleEventObject aEvent
;
759 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
760 aEvent
.EventId
= AccessibleEventId::CHILD
;
761 aEvent
.NewValue
<<= xAcc
;
762 aEvent
.IndexHint
= -1;
763 mpAccDoc
->CommitChange(aEvent
);
768 void ScShapeChildren::FindChanged(ScShapeRange
& rOld
, ScShapeRange
& rNew
) const
770 FindChanged(rOld
.maBackShapes
, rNew
.maBackShapes
);
771 FindChanged(rOld
.maForeShapes
, rNew
.maForeShapes
);
772 FindChanged(rOld
.maControls
, rNew
.maControls
);
775 void ScShapeChildren::DataChanged()
777 ScShapeRangeVec
aOldShapeRanges(std::move(maShapeRanges
));
778 maShapeRanges
.clear();
779 maShapeRanges
.resize(SC_PREVIEW_MAXRANGES
);
781 for (sal_Int32 i
= 0; i
< SC_PREVIEW_MAXRANGES
; ++i
)
783 FindChanged(aOldShapeRanges
[i
], maShapeRanges
[i
]);
789 struct ScVisAreaChanged
791 void operator() (const ScShapeChild
& rAccShapeData
) const
793 if (rAccShapeData
.mpAccShape
.is())
795 rAccShapeData
.mpAccShape
->ViewForwarderChanged();
801 void ScShapeChildren::VisAreaChanged() const
803 for (auto const& shape
: maShapeRanges
)
805 ScVisAreaChanged aVisAreaChanged
;
806 std::for_each(shape
.maBackShapes
.begin(), shape
.maBackShapes
.end(), aVisAreaChanged
);
807 std::for_each(shape
.maControls
.begin(), shape
.maControls
.end(), aVisAreaChanged
);
808 std::for_each(shape
.maForeShapes
.begin(), shape
.maForeShapes
.end(), aVisAreaChanged
);
812 ///===== IAccessibleParent ==============================================
814 bool ScShapeChildren::ReplaceChild (::accessibility::AccessibleShape
* /* pCurrentChild */,
815 const css::uno::Reference
< css::drawing::XShape
>& /* _rxShape */,
816 const tools::Long
/* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo
& /* _rShapeTreeInfo */)
818 OSL_FAIL("should not be called in the page preview");
822 ///===== Internal ========================================================
824 void ScShapeChildren::Init()
829 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
831 tools::Rectangle aPixelPaintRect
;
833 sal_uInt16
nCount(rData
.GetDrawRanges());
834 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
836 rData
.GetDrawRange(i
, aPixelPaintRect
, aMapMode
, nRangeId
);
837 FillShapes(aPixelPaintRect
, aMapMode
, nRangeId
);
841 sal_Int32
ScShapeChildren::GetBackShapeCount() const
844 for (auto const& shape
: maShapeRanges
)
845 nCount
+= shape
.maBackShapes
.size();
849 uno::Reference
<XAccessible
> ScShapeChildren::GetBackShape(sal_Int32 nIndex
) const
851 uno::Reference
<XAccessible
> xAccessible
;
852 for (const auto& rShapeRange
: maShapeRanges
)
854 sal_Int32
nCount(rShapeRange
.maBackShapes
.size());
856 xAccessible
= GetAccShape(rShapeRange
.maBackShapes
, nIndex
);
858 if (xAccessible
.is())
863 throw lang::IndexOutOfBoundsException();
868 sal_Int32
ScShapeChildren::GetForeShapeCount() const
871 for (auto const& shape
: maShapeRanges
)
872 nCount
+= shape
.maForeShapes
.size();
876 uno::Reference
<XAccessible
> ScShapeChildren::GetForeShape(sal_Int32 nIndex
) const
878 uno::Reference
<XAccessible
> xAccessible
;
879 for (const auto& rShapeRange
: maShapeRanges
)
881 sal_Int32
nCount(rShapeRange
.maForeShapes
.size());
883 xAccessible
= GetAccShape(rShapeRange
.maForeShapes
, nIndex
);
885 if (xAccessible
.is())
890 throw lang::IndexOutOfBoundsException();
895 sal_Int32
ScShapeChildren::GetControlCount() const
898 for (auto const& shape
: maShapeRanges
)
899 nCount
+= shape
.maControls
.size();
903 uno::Reference
<XAccessible
> ScShapeChildren::GetControl(sal_Int32 nIndex
) const
905 uno::Reference
<XAccessible
> xAccessible
;
906 for (const auto& rShapeRange
: maShapeRanges
)
908 sal_Int32
nCount(rShapeRange
.maControls
.size());
910 xAccessible
= GetAccShape(rShapeRange
.maControls
, nIndex
);
912 if (xAccessible
.is())
917 throw lang::IndexOutOfBoundsException();
924 struct ScShapePointFound
927 explicit ScShapePointFound(const awt::Point
& rPoint
)
928 : maPoint(vcl::unohelper::ConvertToVCLPoint(rPoint
))
931 bool operator() (const ScShapeChild
& rShape
)
934 if (vcl::unohelper::ConvertToVCLRect(rShape
.mpAccShape
->getBounds()).Contains(maPoint
))
942 uno::Reference
<XAccessible
> ScShapeChildren::GetForegroundShapeAt(const awt::Point
& rPoint
) const //inclusive Controls
944 uno::Reference
<XAccessible
> xAcc
;
946 for(const auto& rShapeRange
: maShapeRanges
)
948 ScShapeChildVec::const_iterator aFindItr
= std::find_if(rShapeRange
.maForeShapes
.begin(), rShapeRange
.maForeShapes
.end(), ScShapePointFound(rPoint
));
949 if (aFindItr
!= rShapeRange
.maForeShapes
.end())
950 xAcc
= GetAccShape(*aFindItr
);
953 ScShapeChildVec::const_iterator aCtrlItr
= std::find_if(rShapeRange
.maControls
.begin(), rShapeRange
.maControls
.end(), ScShapePointFound(rPoint
));
954 if (aCtrlItr
!= rShapeRange
.maControls
.end())
955 xAcc
= GetAccShape(*aCtrlItr
);
965 uno::Reference
<XAccessible
> ScShapeChildren::GetBackgroundShapeAt(const awt::Point
& rPoint
) const
967 uno::Reference
<XAccessible
> xAcc
;
969 for(const auto& rShapeRange
: maShapeRanges
)
971 ScShapeChildVec::const_iterator aFindItr
= std::find_if(rShapeRange
.maBackShapes
.begin(), rShapeRange
.maBackShapes
.end(), ScShapePointFound(rPoint
));
972 if (aFindItr
!= rShapeRange
.maBackShapes
.end())
973 xAcc
= GetAccShape(*aFindItr
);
981 ::accessibility::AccessibleShape
* ScShapeChildren::GetAccShape(const ScShapeChild
& rShape
) const
983 if (!rShape
.mpAccShape
.is())
985 ::accessibility::ShapeTypeHandler
& rShapeHandler
= ::accessibility::ShapeTypeHandler::Instance();
986 ::accessibility::AccessibleShapeInfo
aShapeInfo(rShape
.mxShape
, mpAccDoc
);
990 ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo
;
991 aShapeTreeInfo
.SetSdrView(mpViewShell
->GetPreview()->GetDrawView());
992 aShapeTreeInfo
.SetController(nullptr);
993 aShapeTreeInfo
.SetWindow(mpViewShell
->GetWindow());
994 aShapeTreeInfo
.SetViewForwarder(&(maShapeRanges
[rShape
.mnRangeId
].maViewForwarder
));
995 rShape
.mpAccShape
= rShapeHandler
.CreateAccessibleObject(aShapeInfo
, aShapeTreeInfo
);
996 if (rShape
.mpAccShape
.is())
998 rShape
.mpAccShape
->Init();
1002 return rShape
.mpAccShape
.get();
1005 ::accessibility::AccessibleShape
* ScShapeChildren::GetAccShape(const ScShapeChildVec
& rShapes
, sal_Int32 nIndex
) const
1007 return GetAccShape(rShapes
[nIndex
]);
1010 void ScShapeChildren::FillShapes(const tools::Rectangle
& aPixelPaintRect
, const MapMode
& aMapMode
, sal_uInt8 nRangeId
)
1012 OSL_ENSURE(nRangeId
< maShapeRanges
.size(), "this is not a valid range for draw objects");
1013 SdrPage
* pPage
= GetDrawPage();
1014 vcl::Window
* pWin
= mpViewShell
->GetWindow();
1015 if (!(pPage
&& pWin
))
1018 bool bForeAdded(false);
1019 bool bBackAdded(false);
1020 bool bControlAdded(false);
1021 tools::Rectangle
aClippedPixelPaintRect(aPixelPaintRect
);
1024 tools::Rectangle
aRect2(Point(0,0), mpAccDoc
->GetBoundingBoxOnScreen().GetSize());
1025 aClippedPixelPaintRect
= aPixelPaintRect
.GetIntersection(aRect2
);
1027 maShapeRanges
[nRangeId
].maViewForwarder
= ScIAccessibleViewForwarder(mpViewShell
, mpAccDoc
, aMapMode
);
1028 for (const rtl::Reference
<SdrObject
>& pObj
: *pPage
)
1030 uno::Reference
< drawing::XShape
> xShape(pObj
->getUnoShape(), uno::UNO_QUERY
);
1033 tools::Rectangle
aRect(pWin
->LogicToPixel(
1034 tools::Rectangle(vcl::unohelper::ConvertToVCLPoint(xShape
->getPosition()),
1035 vcl::unohelper::ConvertToVCLSize(xShape
->getSize())), aMapMode
));
1036 if(!aClippedPixelPaintRect
.GetIntersection(aRect
).IsEmpty())
1038 ScShapeChild aShape
;
1039 aShape
.mxShape
= std::move(xShape
);
1040 aShape
.mnRangeId
= nRangeId
;
1041 if (pObj
->GetLayer().anyOf(SC_LAYER_INTERN
, SC_LAYER_FRONT
))
1043 maShapeRanges
[nRangeId
].maForeShapes
.push_back(std::move(aShape
));
1046 else if (pObj
->GetLayer() == SC_LAYER_BACK
)
1048 maShapeRanges
[nRangeId
].maBackShapes
.push_back(std::move(aShape
));
1051 else if (pObj
->GetLayer() == SC_LAYER_CONTROLS
)
1053 maShapeRanges
[nRangeId
].maControls
.push_back(std::move(aShape
));
1054 bControlAdded
= true;
1058 OSL_FAIL("I don't know this layer.");
1064 std::sort(maShapeRanges
[nRangeId
].maForeShapes
.begin(), maShapeRanges
[nRangeId
].maForeShapes
.end(),ScShapeChildLess());
1066 std::sort(maShapeRanges
[nRangeId
].maBackShapes
.begin(), maShapeRanges
[nRangeId
].maBackShapes
.end(),ScShapeChildLess());
1068 std::sort(maShapeRanges
[nRangeId
].maControls
.begin(), maShapeRanges
[nRangeId
].maControls
.end(),ScShapeChildLess());
1071 SdrPage
* ScShapeChildren::GetDrawPage() const
1073 SCTAB
nTab( mpViewShell
->GetLocationData().GetPrintTab() );
1074 SdrPage
* pDrawPage
= nullptr;
1075 ScDocument
& rDoc
= mpViewShell
->GetDocument();
1076 if (rDoc
.GetDrawLayer())
1078 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
1079 if (pDrawLayer
->HasObjects() && (pDrawLayer
->GetPageCount() > nTab
))
1080 pDrawPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(static_cast<sal_Int16
>(nTab
)));
1087 struct ScPagePreviewCountData
1089 // order is background shapes, header, table or notes, footer, foreground shapes, controls
1091 tools::Rectangle aVisRect
;
1092 tools::Long nBackShapes
;
1093 tools::Long nHeaders
;
1094 tools::Long nTables
;
1095 tools::Long nNoteParagraphs
;
1096 tools::Long nFooters
;
1097 tools::Long nForeShapes
;
1098 tools::Long nControls
;
1100 ScPagePreviewCountData( const ScPreviewLocationData
& rData
, const vcl::Window
* pSizeWindow
,
1101 const ScNotesChildren
* pNotesChildren
, const ScShapeChildren
* pShapeChildren
);
1103 tools::Long
GetTotal() const
1105 return nBackShapes
+ nHeaders
+ nTables
+ nNoteParagraphs
+ nFooters
+ nForeShapes
+ nControls
;
1111 ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData
& rData
,
1112 const vcl::Window
* pSizeWindow
, const ScNotesChildren
* pNotesChildren
,
1113 const ScShapeChildren
* pShapeChildren
) :
1117 nNoteParagraphs( 0 ),
1124 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1125 aVisRect
= tools::Rectangle( Point(), aOutputSize
);
1127 tools::Rectangle aObjRect
;
1129 if ( rData
.GetHeaderPosition( aObjRect
) && aObjRect
.Overlaps( aVisRect
) )
1132 if ( rData
.GetFooterPosition( aObjRect
) && aObjRect
.Overlaps( aVisRect
) )
1135 if ( rData
.HasCellsInRange( aVisRect
) )
1139 nBackShapes
= pShapeChildren
->GetBackShapeCount();
1140 nForeShapes
= pShapeChildren
->GetForeShapeCount();
1141 nControls
= pShapeChildren
->GetControlCount();
1143 // there are only notes if there is no table
1145 nNoteParagraphs
= pNotesChildren
->GetChildrenCount();
1148 //===== internal ========================================================
1150 ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
1151 const uno::Reference
<XAccessible
>& rxParent
, ScPreviewShell
* pViewShell
) :
1152 ScAccessibleDocumentBase(rxParent
),
1153 mpViewShell(pViewShell
)
1156 pViewShell
->AddAccessibilityObject(*this);
1160 ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview()
1162 if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper
.bInDispose
)
1164 // increment refcount to prevent double call off dtor
1165 osl_atomic_increment( &m_refCount
);
1166 // call dispose to inform object which have a weak reference to this object
1171 void SAL_CALL
ScAccessibleDocumentPagePreview::disposing()
1173 SolarMutexGuard aGuard
;
1180 mpViewShell
->RemoveAccessibilityObject(*this);
1181 mpViewShell
= nullptr;
1184 // no need to Dispose the AccessibleTextHelper,
1185 // as long as mpNotesChildren are destructed here
1186 mpNotesChildren
.reset();
1188 mpShapeChildren
.reset();
1190 ScAccessibleDocumentBase::disposing();
1193 //===== SfxListener =====================================================
1195 void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1197 if ( rHint
.GetId() == SfxHintId::ScAccWinFocusLost
)
1201 else if ( rHint
.GetId() == SfxHintId::ScAccGridWinFocusLost
)
1205 else if ( rHint
.GetId() == SfxHintId::ScAccWinFocusGot
)
1207 CommitFocusGained();
1209 else if ( rHint
.GetId() == SfxHintId::ScAccGridWinFocusGot
)
1211 CommitFocusGained();
1213 else if (rHint
.GetId() == SfxHintId::ScDataChanged
)
1215 // only notify if child exist, otherwise it is not necessary
1216 if (mpTable
.is()) // if there is no table there is nothing to notify, because no one recognizes the change
1219 uno::Reference
<XAccessible
> xAcc
= mpTable
;
1220 AccessibleEventObject aEvent
;
1221 aEvent
.EventId
= AccessibleEventId::CHILD
;
1222 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1223 aEvent
.OldValue
<<= xAcc
;
1224 aEvent
.IndexHint
= -1;
1225 CommitChange(aEvent
);
1233 vcl::Window
* pSizeWindow
= mpViewShell
->GetWindow();
1235 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1236 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1237 GetNotesChildren()->DataChanged(aVisRect
);
1239 GetShapeChildren()->DataChanged();
1241 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1242 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1244 if (aCount
.nTables
> 0)
1246 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1247 sal_Int32
nIndex (aCount
.nBackShapes
+ aCount
.nHeaders
);
1249 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1253 uno::Reference
<XAccessible
> xAcc
= mpTable
;
1254 AccessibleEventObject aEvent
;
1255 aEvent
.EventId
= AccessibleEventId::CHILD
;
1256 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1257 aEvent
.NewValue
<<= xAcc
;
1258 aEvent
.IndexHint
= -1;
1259 CommitChange(aEvent
);
1263 else if (rHint
.GetId() == SfxHintId::ScAccVisAreaChanged
)
1266 vcl::Window
* pSizeWindow
= mpViewShell
->GetWindow();
1268 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1269 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1270 GetNotesChildren()->DataChanged(aVisRect
);
1272 GetShapeChildren()->VisAreaChanged();
1274 AccessibleEventObject aEvent
;
1275 aEvent
.EventId
= AccessibleEventId::VISIBLE_DATA_CHANGED
;
1276 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1277 CommitChange(aEvent
);
1279 ScAccessibleDocumentBase::Notify(rBC
, rHint
);
1282 //===== XAccessibleComponent ============================================
1284 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point
& rPoint
)
1286 uno::Reference
<XAccessible
> xAccessible
;
1287 if (containsPoint(rPoint
))
1289 SolarMutexGuard aGuard
;
1294 xAccessible
= GetShapeChildren()->GetForegroundShapeAt(rPoint
);
1295 if (!xAccessible
.is())
1297 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1298 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1300 if ( !mpTable
.is() && (aCount
.nTables
> 0) )
1302 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1303 sal_Int32
nIndex (aCount
.nBackShapes
+ aCount
.nHeaders
);
1305 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1309 && vcl::unohelper::ConvertToVCLRect(mpTable
->getBounds())
1310 .Contains(vcl::unohelper::ConvertToVCLPoint(rPoint
)))
1311 xAccessible
= mpTable
.get();
1313 if (!xAccessible
.is())
1314 xAccessible
= GetNotesChildren()->GetAt(rPoint
);
1315 if (!xAccessible
.is())
1317 if (!mpHeader
.is() || !mpFooter
.is())
1319 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1320 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1324 mpHeader
= new ScAccessiblePageHeader( this, mpViewShell
, true, aCount
.nBackShapes
+ aCount
.nHeaders
- 1);
1328 mpFooter
= new ScAccessiblePageHeader( this, mpViewShell
, false, aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
- 1 );
1332 Point
aPoint(vcl::unohelper::ConvertToVCLPoint(rPoint
));
1334 if (vcl::unohelper::ConvertToVCLRect(mpHeader
->getBounds()).Contains(aPoint
))
1335 xAccessible
= mpHeader
.get();
1336 else if (vcl::unohelper::ConvertToVCLRect(mpFooter
->getBounds()).Contains(aPoint
))
1337 xAccessible
= mpFooter
.get();
1339 if (!xAccessible
.is())
1340 xAccessible
= GetShapeChildren()->GetBackgroundShapeAt(rPoint
);
1347 void SAL_CALL
ScAccessibleDocumentPagePreview::grabFocus()
1349 SolarMutexGuard aGuard
;
1351 if (getAccessibleParent().is())
1353 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
1354 if (xAccessibleComponent
.is())
1356 // just grab the focus for the window
1357 xAccessibleComponent
->grabFocus();
1362 //===== XAccessibleContext ==============================================
1364 sal_Int64 SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleChildCount()
1366 SolarMutexGuard aGuard
;
1372 ScPagePreviewCountData
aCount( mpViewShell
->GetLocationData(), mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1373 nRet
= aCount
.GetTotal();
1379 uno::Reference
<XAccessible
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int64 nIndex
)
1381 SolarMutexGuard aGuard
;
1383 uno::Reference
<XAccessible
> xAccessible
;
1387 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1388 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1390 if ( nIndex
< aCount
.nBackShapes
)
1392 xAccessible
= GetShapeChildren()->GetBackShape(nIndex
);
1394 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
)
1396 if ( !mpHeader
.is() )
1398 mpHeader
= new ScAccessiblePageHeader( this, mpViewShell
, true, nIndex
);
1401 xAccessible
= mpHeader
.get();
1403 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
)
1405 if ( !mpTable
.is() )
1407 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1410 xAccessible
= mpTable
.get();
1412 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nNoteParagraphs
)
1414 xAccessible
= GetNotesChildren()->GetChild(nIndex
- aCount
.nBackShapes
- aCount
.nHeaders
);
1416 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
)
1418 if ( !mpFooter
.is() )
1420 mpFooter
= new ScAccessiblePageHeader( this, mpViewShell
, false, nIndex
);
1422 xAccessible
= mpFooter
.get();
1426 sal_Int64
nIdx(nIndex
- (aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
));
1427 if (nIdx
< aCount
.nForeShapes
)
1428 xAccessible
= GetShapeChildren()->GetForeShape(nIdx
);
1430 xAccessible
= GetShapeChildren()->GetControl(nIdx
- aCount
.nForeShapes
);
1434 if ( !xAccessible
.is() )
1435 throw lang::IndexOutOfBoundsException();
1440 /// Return the set of current states.
1441 sal_Int64 SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleStateSet()
1443 SolarMutexGuard aGuard
;
1444 sal_Int64 nParentStates
= 0;
1445 if (getAccessibleParent().is())
1447 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
1448 nParentStates
= xParentContext
->getAccessibleStateSet();
1450 sal_Int64 nStateSet
= 0;
1451 if (IsDefunc(nParentStates
))
1452 nStateSet
|= AccessibleStateType::DEFUNC
;
1456 nStateSet
|= AccessibleStateType::ENABLED
;
1457 nStateSet
|= AccessibleStateType::OPAQUE
;
1459 nStateSet
|= AccessibleStateType::SHOWING
;
1461 nStateSet
|= AccessibleStateType::VISIBLE
;
1466 //===== XServiceInfo ====================================================
1468 OUString SAL_CALL
ScAccessibleDocumentPagePreview::getImplementationName()
1470 return u
"ScAccessibleDocumentPagePreview"_ustr
;
1473 uno::Sequence
< OUString
> SAL_CALL
ScAccessibleDocumentPagePreview::getSupportedServiceNames()
1475 const css::uno::Sequence
<OUString
> vals
{ u
"com.sun.star.AccessibleSpreadsheetPageView"_ustr
};
1476 return comphelper::concatSequences(ScAccessibleContextBase::getSupportedServiceNames(), vals
);
1479 //===== XTypeProvider =======================================================
1481 uno::Sequence
<sal_Int8
> SAL_CALL
1482 ScAccessibleDocumentPagePreview::getImplementationId()
1484 return css::uno::Sequence
<sal_Int8
>();
1487 //===== internal ========================================================
1489 OUString
ScAccessibleDocumentPagePreview::createAccessibleDescription()
1491 return STR_ACC_PREVIEWDOC_DESCR
;
1494 OUString
ScAccessibleDocumentPagePreview::createAccessibleName()
1496 OUString sName
= ScResId(STR_ACC_PREVIEWDOC_NAME
);
1500 AbsoluteScreenPixelRectangle
ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const
1502 AbsoluteScreenPixelRectangle aRect
;
1505 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1507 aRect
= pWindow
->GetWindowExtentsAbsolute();
1512 tools::Rectangle
ScAccessibleDocumentPagePreview::GetBoundingBox() const
1514 tools::Rectangle aRect
;
1517 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1519 aRect
= pWindow
->GetWindowExtentsRelative(*pWindow
->GetAccessibleParentWindow());
1524 bool ScAccessibleDocumentPagePreview::IsDefunc(sal_Int64 nParentStates
)
1526 return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
1527 (nParentStates
& AccessibleStateType::DEFUNC
);
1530 ScNotesChildren
* ScAccessibleDocumentPagePreview::GetNotesChildren()
1532 if (!mpNotesChildren
&& mpViewShell
)
1534 mpNotesChildren
.reset( new ScNotesChildren(mpViewShell
, this) );
1536 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1537 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1539 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1540 mpNotesChildren
->Init(aCount
.aVisRect
, aCount
.nBackShapes
+ aCount
.nHeaders
);
1542 return mpNotesChildren
.get();
1545 ScShapeChildren
* ScAccessibleDocumentPagePreview::GetShapeChildren()
1547 if (!mpShapeChildren
&& mpViewShell
)
1549 mpShapeChildren
.reset( new ScShapeChildren(mpViewShell
, this) );
1550 mpShapeChildren
->Init();
1553 return mpShapeChildren
.get();
1556 OUString
ScAccessibleDocumentPagePreview::getAccessibleName()
1560 OUString aName
= ScResId(STR_ACC_DOC_SPREADSHEET
);
1561 ScDocument
& rScDoc
= mpViewShell
->GetDocument();
1563 ScDocShell
* pObjSh
= rScDoc
.GetDocumentShell();
1568 SfxMedium
* pMed
= pObjSh
->GetMedium();
1570 aFileName
= pMed
->GetName();
1572 if (aFileName
.isEmpty())
1573 aFileName
= pObjSh
->GetTitle(SFX_TITLE_APINAME
);
1575 if (!aFileName
.isEmpty())
1577 aName
= aFileName
+ " - " + aName
+ ScResId(STR_ACC_DOC_PREVIEW_SUFFIX
);
1584 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */