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>
40 #include <unotools/accessiblestatesethelper.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/convert.hxx>
52 #include <vcl/svapp.hxx>
53 #include <sfx2/docfile.hxx>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::accessibility
;
63 typedef std::vector
< uno::Reference
< XAccessible
> > ScXAccVector
;
70 tools::Rectangle maRect
;
72 ::accessibility::AccessibleTextHelper
* mpTextHelper
;
73 sal_Int32 mnParaCount
;
77 : mpTextHelper(nullptr)
89 ScNotesChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
);
91 void Init(const tools::Rectangle
& rVisRect
, sal_Int32 nOffset
);
93 sal_Int32
GetChildrenCount() const { return mnParagraphs
;}
94 uno::Reference
<XAccessible
> GetChild(sal_Int32 nIndex
) const;
95 uno::Reference
<XAccessible
> GetAt(const awt::Point
& rPoint
) const;
97 void DataChanged(const tools::Rectangle
& rVisRect
);
100 ScPreviewShell
* mpViewShell
;
101 ScAccessibleDocumentPagePreview
* mpAccDoc
;
102 typedef std::vector
<ScAccNote
> ScAccNotes
;
103 mutable ScAccNotes maNotes
;
104 mutable ScAccNotes maMarks
;
105 sal_Int32 mnParagraphs
;
108 ::accessibility::AccessibleTextHelper
* CreateTextHelper(const OUString
& rString
, const tools::Rectangle
& rVisRect
, const ScAddress
& aCellPos
, bool bMarkNote
, sal_Int32 nChildOffset
) const;
109 sal_Int32
AddNotes(const ScPreviewLocationData
& rData
, const tools::Rectangle
& rVisRect
, bool bMark
, ScAccNotes
& rNotes
);
111 static sal_Int8
CompareCell(const ScAddress
& aCell1
, const ScAddress
& aCell2
);
112 static void CollectChildren(const ScAccNote
& rNote
, ScXAccVector
& rVector
);
113 sal_Int32
CheckChanges(const ScPreviewLocationData
& rData
, const tools::Rectangle
& rVisRect
,
114 bool bMark
, ScAccNotes
& rOldNotes
, ScAccNotes
& rNewNotes
,
115 ScXAccVector
& rOldParas
, ScXAccVector
& rNewParas
);
117 inline ScDocument
* GetDocument() const;
120 ScNotesChildren::ScNotesChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
)
121 : mpViewShell(pViewShell
),
128 ScNotesChildren::~ScNotesChildren()
130 for (auto & i
: maNotes
)
133 delete i
.mpTextHelper
;
134 i
.mpTextHelper
= nullptr;
136 for (auto & i
: maMarks
)
139 delete i
.mpTextHelper
;
140 i
.mpTextHelper
= nullptr;
144 ::accessibility::AccessibleTextHelper
* ScNotesChildren::CreateTextHelper(const OUString
& rString
, const tools::Rectangle
& rVisRect
, const ScAddress
& aCellPos
, bool bMarkNote
, sal_Int32 nChildOffset
) const
146 ::accessibility::AccessibleTextHelper
* pTextHelper
= new ::accessibility::AccessibleTextHelper(std::make_unique
<ScAccessibilityEditSource
>(std::make_unique
<ScAccessibleNoteTextData
>(mpViewShell
, rString
, aCellPos
, bMarkNote
)));
147 pTextHelper
->SetEventSource(mpAccDoc
);
148 pTextHelper
->SetStartIndex(nChildOffset
);
149 pTextHelper
->SetOffset(rVisRect
.TopLeft());
154 sal_Int32
ScNotesChildren::AddNotes(const ScPreviewLocationData
& rData
, const tools::Rectangle
& rVisRect
, bool bMark
, ScAccNotes
& rNotes
)
156 sal_Int32 nCount
= rData
.GetNoteCountInRange(rVisRect
, bMark
);
158 rNotes
.reserve(nCount
);
160 sal_Int32
nParagraphs(0);
161 ScDocument
* pDoc
= GetDocument();
165 aNote
.mbMarkNote
= bMark
;
167 aNote
.mnParaCount
= 1;
168 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
170 if (rData
.GetNoteInRange(rVisRect
, nIndex
, bMark
, aNote
.maNoteCell
, aNote
.maRect
))
174 // Document not needed, because only the cell address, but not the tablename is needed
175 aNote
.maNoteText
= aNote
.maNoteCell
.Format(ScRefFlags::VALID
);
179 if( ScPostIt
* pNote
= pDoc
->GetNote( aNote
.maNoteCell
) )
180 aNote
.maNoteText
= pNote
->GetText();
181 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
182 if (aNote
.mpTextHelper
)
183 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
185 nParagraphs
+= aNote
.mnParaCount
;
186 rNotes
.push_back(aNote
);
193 void ScNotesChildren::Init(const tools::Rectangle
& rVisRect
, sal_Int32 nOffset
)
195 if (mpViewShell
&& !mnParagraphs
)
198 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
200 mnParagraphs
= AddNotes(rData
, rVisRect
, false, maMarks
);
201 mnParagraphs
+= AddNotes(rData
, rVisRect
, true, maNotes
);
210 explicit ScParaFound(sal_Int32 nIndex
) : mnIndex(nIndex
) {}
211 bool operator() (const ScAccNote
& rNote
)
214 if (rNote
.mnParaCount
> mnIndex
)
217 mnIndex
-= rNote
.mnParaCount
;
224 uno::Reference
<XAccessible
> ScNotesChildren::GetChild(sal_Int32 nIndex
) const
226 uno::Reference
<XAccessible
> xAccessible
;
228 if (nIndex
< mnParagraphs
)
230 if (nIndex
< static_cast<sal_Int32
>(maMarks
.size()))
232 ScAccNotes::iterator aEndItr
= maMarks
.end();
233 ScParaFound
aParaFound(nIndex
);
234 ScAccNotes::iterator aItr
= std::find_if(maMarks
.begin(), aEndItr
, aParaFound
);
237 OSL_ENSURE((aItr
->maNoteCell
== maMarks
[nIndex
].maNoteCell
) && (aItr
->mbMarkNote
== maMarks
[nIndex
].mbMarkNote
), "wrong note found");
238 if (!aItr
->mpTextHelper
)
239 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
240 xAccessible
= aItr
->mpTextHelper
->GetChild(aParaFound
.mnIndex
+ aItr
->mpTextHelper
->GetStartIndex());
244 OSL_FAIL("wrong note found");
249 nIndex
-= maMarks
.size();
250 ScAccNotes::iterator aEndItr
= maNotes
.end();
251 ScParaFound
aParaFound(nIndex
);
252 ScAccNotes::iterator aItr
= std::find_if(maNotes
.begin(), aEndItr
, aParaFound
);
255 if (!aItr
->mpTextHelper
)
256 aItr
->mpTextHelper
= CreateTextHelper(aItr
->maNoteText
, aItr
->maRect
, aItr
->maNoteCell
, aItr
->mbMarkNote
, (nIndex
- aParaFound
.mnIndex
) + mnOffset
+ maMarks
.size());
257 xAccessible
= aItr
->mpTextHelper
->GetChild(aParaFound
.mnIndex
+ aItr
->mpTextHelper
->GetStartIndex());
269 tools::Rectangle maPoint
;
270 sal_Int32 mnParagraphs
;
271 explicit ScPointFound(const Point
& rPoint
) : maPoint(rPoint
, Size(0, 0)), mnParagraphs(0) {}
272 bool operator() (const ScAccNote
& rNote
)
275 if (maPoint
.IsInside(rNote
.maRect
))
278 mnParagraphs
+= rNote
.mnParaCount
;
285 uno::Reference
<XAccessible
> ScNotesChildren::GetAt(const awt::Point
& rPoint
) const
287 uno::Reference
<XAccessible
> xAccessible
;
289 ScPointFound
aPointFound(Point(rPoint
.X
, rPoint
.Y
));
291 ScAccNotes::iterator aEndItr
= maMarks
.end();
292 ScAccNotes::iterator aItr
= std::find_if(maMarks
.begin(), aEndItr
, aPointFound
);
295 aEndItr
= maNotes
.end();
296 aItr
= std::find_if(maNotes
.begin(), aEndItr
, aPointFound
);
300 if (!aItr
->mpTextHelper
)
301 aItr
->mpTextHelper
= CreateTextHelper(aItr
->maNoteText
, aItr
->maRect
, aItr
->maNoteCell
, aItr
->mbMarkNote
, aPointFound
.mnParagraphs
+ mnOffset
);
302 xAccessible
= aItr
->mpTextHelper
->GetAt(rPoint
);
308 sal_Int8
ScNotesChildren::CompareCell(const ScAddress
& aCell1
, const ScAddress
& aCell2
)
310 OSL_ENSURE(aCell1
.Tab() == aCell2
.Tab(), "the notes should be on the same table");
312 if (aCell1
!= aCell2
)
314 if (aCell1
.Row() == aCell2
.Row())
315 nResult
= (aCell1
.Col() < aCell2
.Col()) ? -1 : 1;
317 nResult
= (aCell1
.Row() < aCell2
.Row()) ? -1 : 1;
322 void ScNotesChildren::CollectChildren(const ScAccNote
& rNote
, ScXAccVector
& rVector
)
324 if (rNote
.mpTextHelper
)
325 for (sal_Int32 i
= 0; i
< rNote
.mnParaCount
; ++i
)
326 rVector
.push_back(rNote
.mpTextHelper
->GetChild(i
+ rNote
.mpTextHelper
->GetStartIndex()));
329 sal_Int32
ScNotesChildren::CheckChanges(const ScPreviewLocationData
& rData
,
330 const tools::Rectangle
& rVisRect
, bool bMark
, ScAccNotes
& rOldNotes
,
331 ScAccNotes
& rNewNotes
, ScXAccVector
& rOldParas
, ScXAccVector
& rNewParas
)
333 sal_Int32 nCount
= rData
.GetNoteCountInRange(rVisRect
, bMark
);
335 rNewNotes
.reserve(nCount
);
337 sal_Int32
nParagraphs(0);
338 ScDocument
* pDoc
= GetDocument();
342 aNote
.mbMarkNote
= bMark
;
344 aNote
.mnParaCount
= 1;
345 ScAccNotes::iterator aItr
= rOldNotes
.begin();
346 ScAccNotes::iterator aEndItr
= rOldNotes
.end();
347 bool bAddNote(false);
348 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
350 if (rData
.GetNoteInRange(rVisRect
, nIndex
, bMark
, aNote
.maNoteCell
, aNote
.maRect
))
354 // Document not needed, because only the cell address, but not the tablename is needed
355 aNote
.maNoteText
= aNote
.maNoteCell
.Format(ScRefFlags::VALID
);
359 if( ScPostIt
* pNote
= pDoc
->GetNote( aNote
.maNoteCell
) )
360 aNote
.maNoteText
= pNote
->GetText();
363 sal_Int8
nCompare(-1); // if there are no more old children it is always a new one
365 nCompare
= CompareCell(aNote
.maNoteCell
, aItr
->maNoteCell
);
368 if (aNote
.maNoteText
== aItr
->maNoteText
)
370 aNote
.mpTextHelper
= aItr
->mpTextHelper
;
371 if (aNote
.maRect
!= aItr
->maRect
) // set new VisArea
373 aNote
.mpTextHelper
->SetOffset(aNote
.maRect
.TopLeft());
374 aNote
.mpTextHelper
->UpdateChildren();
375 //OSL_ENSURE(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
376 // could be changed, because only a part of the note is visible
381 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
382 if (aNote
.mpTextHelper
)
383 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
384 // collect removed children
385 CollectChildren(*aItr
, rOldParas
);
386 delete aItr
->mpTextHelper
;
387 aItr
->mpTextHelper
= nullptr;;
388 // collect new children
389 CollectChildren(aNote
, rNewParas
);
392 // not necessary, because this branch should not be reached if it is the end
393 //if (aItr != aEndItr)
396 else if (nCompare
< 0)
398 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
399 if (aNote
.mpTextHelper
)
400 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
401 // collect new children
402 CollectChildren(aNote
, rNewParas
);
407 // collect removed children
408 CollectChildren(*aItr
, rOldParas
);
409 delete aItr
->mpTextHelper
;
410 aItr
->mpTextHelper
= nullptr;
413 // not necessary, because this branch should not be reached if it is the end
414 //if (aItr != aEndItr)
419 nParagraphs
+= aNote
.mnParaCount
;
420 rNewNotes
.push_back(aNote
);
433 ScAccessibleDocumentPagePreview
* mpAccDoc
;
434 explicit ScChildGone(ScAccessibleDocumentPagePreview
* pAccDoc
) : mpAccDoc(pAccDoc
) {}
435 void operator() (const uno::Reference
<XAccessible
>& xAccessible
) const
439 AccessibleEventObject aEvent
;
440 aEvent
.EventId
= AccessibleEventId::CHILD
;
441 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccDoc
);
442 aEvent
.OldValue
<<= xAccessible
;
444 mpAccDoc
->CommitChange(aEvent
); // gone child - event
451 ScAccessibleDocumentPagePreview
* mpAccDoc
;
452 explicit ScChildNew(ScAccessibleDocumentPagePreview
* pAccDoc
) : mpAccDoc(pAccDoc
) {}
453 void operator() (const uno::Reference
<XAccessible
>& xAccessible
) const
457 AccessibleEventObject aEvent
;
458 aEvent
.EventId
= AccessibleEventId::CHILD
;
459 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccDoc
);
460 aEvent
.NewValue
<<= xAccessible
;
462 mpAccDoc
->CommitChange(aEvent
); // new child - event
469 void ScNotesChildren::DataChanged(const tools::Rectangle
& rVisRect
)
471 if (!(mpViewShell
&& mpAccDoc
))
474 ScXAccVector aNewParas
;
475 ScXAccVector aOldParas
;
476 ScAccNotes aNewMarks
;
477 mnParagraphs
= CheckChanges(mpViewShell
->GetLocationData(), rVisRect
, true, maMarks
, aNewMarks
, aOldParas
, aNewParas
);
479 ScAccNotes aNewNotes
;
480 mnParagraphs
+= CheckChanges(mpViewShell
->GetLocationData(), rVisRect
, false, maNotes
, aNewNotes
, aOldParas
, aNewParas
);
483 std::for_each(aOldParas
.begin(), aOldParas
.end(), ScChildGone(mpAccDoc
));
484 std::for_each(aNewParas
.begin(), aNewParas
.end(), ScChildNew(mpAccDoc
));
487 inline ScDocument
* ScNotesChildren::GetDocument() const
489 ScDocument
* pDoc
= nullptr;
491 pDoc
= &mpViewShell
->GetDocument();
497 class ScIAccessibleViewForwarder
: public ::accessibility::IAccessibleViewForwarder
500 ScIAccessibleViewForwarder();
501 ScIAccessibleViewForwarder(ScPreviewShell
* pViewShell
,
502 ScAccessibleDocumentPagePreview
* pAccDoc
,
503 const MapMode
& aMapMode
);
505 ///===== IAccessibleViewForwarder ========================================
507 virtual tools::Rectangle
GetVisibleArea() const override
;
508 virtual Point
LogicToPixel (const Point
& rPoint
) const override
;
509 virtual Size
LogicToPixel (const Size
& rSize
) const override
;
512 ScPreviewShell
* mpViewShell
;
513 ScAccessibleDocumentPagePreview
* mpAccDoc
;
519 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
520 : mpViewShell(nullptr), mpAccDoc(nullptr)
524 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell
* pViewShell
,
525 ScAccessibleDocumentPagePreview
* pAccDoc
,
526 const MapMode
& aMapMode
)
527 : mpViewShell(pViewShell
),
533 ///===== IAccessibleViewForwarder ========================================
535 tools::Rectangle
ScIAccessibleViewForwarder::GetVisibleArea() const
537 SolarMutexGuard aGuard
;
538 tools::Rectangle aVisRect
;
539 vcl::Window
* pWin
= mpViewShell
->GetWindow();
542 aVisRect
.SetSize(pWin
->GetOutputSizePixel());
543 aVisRect
.SetPos(Point(0, 0));
545 aVisRect
= pWin
->PixelToLogic(aVisRect
, maMapMode
);
551 Point
ScIAccessibleViewForwarder::LogicToPixel (const Point
& rPoint
) const
553 SolarMutexGuard aGuard
;
555 vcl::Window
* pWin
= mpViewShell
->GetWindow();
556 if (pWin
&& mpAccDoc
)
558 tools::Rectangle
aRect(mpAccDoc
->GetBoundingBoxOnScreen());
559 aPoint
= pWin
->LogicToPixel(rPoint
, maMapMode
) + aRect
.TopLeft();
565 Size
ScIAccessibleViewForwarder::LogicToPixel (const Size
& rSize
) const
567 SolarMutexGuard aGuard
;
569 vcl::Window
* pWin
= mpViewShell
->GetWindow();
571 aSize
= pWin
->LogicToPixel(rSize
, maMapMode
);
583 ScShapeChild(ScShapeChild
const &) = delete;
584 ScShapeChild(ScShapeChild
&&) = default;
586 ScShapeChild
& operator =(ScShapeChild
const &) = delete;
587 ScShapeChild
& operator =(ScShapeChild
&& other
) {
588 std::swap(mpAccShape
, other
.mpAccShape
);
589 mxShape
= std::move(other
.mxShape
);
590 mnRangeId
= other
.mnRangeId
;
594 mutable rtl::Reference
< ::accessibility::AccessibleShape
> mpAccShape
;
595 css::uno::Reference
< css::drawing::XShape
> mxShape
;
601 ScShapeChild::~ScShapeChild()
605 mpAccShape
->dispose();
611 struct ScShapeChildLess
613 bool operator()(const ScShapeChild
& rChild1
, const ScShapeChild
& rChild2
) const
616 if (rChild1
.mxShape
.is() && rChild2
.mxShape
.is())
617 bResult
= (rChild1
.mxShape
.get() < rChild2
.mxShape
.get());
624 typedef std::vector
<ScShapeChild
> ScShapeChildVec
;
630 ScShapeRange() = default;
631 ScShapeRange(ScShapeRange
const &) = delete;
632 ScShapeRange(ScShapeRange
&&) = default;
633 ScShapeRange
& operator =(ScShapeRange
const &) = delete;
634 ScShapeRange
& operator =(ScShapeRange
&&) = default;
636 ScShapeChildVec maBackShapes
;
637 ScShapeChildVec maForeShapes
; // inclusive internal shapes
638 ScShapeChildVec maControls
;
639 ScIAccessibleViewForwarder maViewForwarder
;
644 typedef std::vector
<ScShapeRange
> ScShapeRangeVec
;
646 class ScShapeChildren
: public ::accessibility::IAccessibleParent
649 ScShapeChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
);
651 ///===== IAccessibleParent ==============================================
653 virtual bool ReplaceChild (
654 ::accessibility::AccessibleShape
* pCurrentChild
,
655 const css::uno::Reference
< css::drawing::XShape
>& _rxShape
,
656 const tools::Long _nIndex
,
657 const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
660 ///===== Internal ========================================================
664 sal_Int32
GetBackShapeCount() const;
665 uno::Reference
<XAccessible
> GetBackShape(sal_Int32 nIndex
) const;
666 sal_Int32
GetForeShapeCount() const;
667 uno::Reference
<XAccessible
> GetForeShape(sal_Int32 nIndex
) const;
668 sal_Int32
GetControlCount() const;
669 uno::Reference
<XAccessible
> GetControl(sal_Int32 nIndex
) const;
670 uno::Reference
<XAccessible
> GetForegroundShapeAt(const awt::Point
& rPoint
) const; // inclusive controls
671 uno::Reference
<XAccessible
> GetBackgroundShapeAt(const awt::Point
& rPoint
) const;
674 void VisAreaChanged() const;
677 ScAccessibleDocumentPagePreview
* mpAccDoc
;
678 ScPreviewShell
* mpViewShell
;
679 ScShapeRangeVec maShapeRanges
;
681 void FindChanged(ScShapeChildVec
& aOld
, ScShapeChildVec
& aNew
) const;
682 void FindChanged(ScShapeRange
& aOld
, ScShapeRange
& aNew
) const;
683 ::accessibility::AccessibleShape
* GetAccShape(const ScShapeChild
& rShape
) const;
684 ::accessibility::AccessibleShape
* GetAccShape(const ScShapeChildVec
& rShapes
, sal_Int32 nIndex
) const;
685 void FillShapes(const tools::Rectangle
& aPixelPaintRect
, const MapMode
& aMapMode
, sal_uInt8 nRangeId
);
687 // void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
688 // void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
689 SdrPage
* GetDrawPage() const;
692 ScShapeChildren::ScShapeChildren(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
)
695 mpViewShell(pViewShell
),
696 maShapeRanges(SC_PREVIEW_MAXRANGES
)
700 void ScShapeChildren::FindChanged(ScShapeChildVec
& rOld
, ScShapeChildVec
& rNew
) const
702 ScShapeChildVec::iterator aOldItr
= rOld
.begin();
703 ScShapeChildVec::iterator aOldEnd
= rOld
.end();
704 ScShapeChildVec::const_iterator aNewItr
= rNew
.begin();
705 ScShapeChildVec::const_iterator aNewEnd
= rNew
.end();
706 uno::Reference
<XAccessible
> xAcc
;
707 while ((aNewItr
!= aNewEnd
) && (aOldItr
!= aOldEnd
))
709 if (aNewItr
->mxShape
.get() == aOldItr
->mxShape
.get())
714 else if (aNewItr
->mxShape
.get() < aOldItr
->mxShape
.get())
716 xAcc
= GetAccShape(*aNewItr
);
717 AccessibleEventObject aEvent
;
718 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
719 aEvent
.EventId
= AccessibleEventId::CHILD
;
720 aEvent
.NewValue
<<= xAcc
;
721 mpAccDoc
->CommitChange(aEvent
);
726 xAcc
= GetAccShape(*aOldItr
);
727 AccessibleEventObject aEvent
;
728 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
729 aEvent
.EventId
= AccessibleEventId::CHILD
;
730 aEvent
.OldValue
<<= xAcc
;
731 mpAccDoc
->CommitChange(aEvent
);
735 while (aOldItr
!= aOldEnd
)
737 xAcc
= GetAccShape(*aOldItr
);
738 AccessibleEventObject aEvent
;
739 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
740 aEvent
.EventId
= AccessibleEventId::CHILD
;
741 aEvent
.OldValue
<<= xAcc
;
742 mpAccDoc
->CommitChange(aEvent
);
745 while (aNewItr
!= aNewEnd
)
747 xAcc
= GetAccShape(*aNewItr
);
748 AccessibleEventObject aEvent
;
749 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
750 aEvent
.EventId
= AccessibleEventId::CHILD
;
751 aEvent
.NewValue
<<= xAcc
;
752 mpAccDoc
->CommitChange(aEvent
);
757 void ScShapeChildren::FindChanged(ScShapeRange
& rOld
, ScShapeRange
& rNew
) const
759 FindChanged(rOld
.maBackShapes
, rNew
.maBackShapes
);
760 FindChanged(rOld
.maForeShapes
, rNew
.maForeShapes
);
761 FindChanged(rOld
.maControls
, rNew
.maControls
);
764 void ScShapeChildren::DataChanged()
766 ScShapeRangeVec
aOldShapeRanges(std::move(maShapeRanges
));
767 maShapeRanges
.clear();
768 maShapeRanges
.resize(SC_PREVIEW_MAXRANGES
);
770 for (sal_Int32 i
= 0; i
< SC_PREVIEW_MAXRANGES
; ++i
)
772 FindChanged(aOldShapeRanges
[i
], maShapeRanges
[i
]);
778 struct ScVisAreaChanged
780 void operator() (const ScShapeChild
& rAccShapeData
) const
782 if (rAccShapeData
.mpAccShape
.is())
784 rAccShapeData
.mpAccShape
->ViewForwarderChanged();
790 void ScShapeChildren::VisAreaChanged() const
792 for (auto const& shape
: maShapeRanges
)
794 ScVisAreaChanged aVisAreaChanged
;
795 std::for_each(shape
.maBackShapes
.begin(), shape
.maBackShapes
.end(), aVisAreaChanged
);
796 std::for_each(shape
.maControls
.begin(), shape
.maControls
.end(), aVisAreaChanged
);
797 std::for_each(shape
.maForeShapes
.begin(), shape
.maForeShapes
.end(), aVisAreaChanged
);
801 ///===== IAccessibleParent ==============================================
803 bool ScShapeChildren::ReplaceChild (::accessibility::AccessibleShape
* /* pCurrentChild */,
804 const css::uno::Reference
< css::drawing::XShape
>& /* _rxShape */,
805 const tools::Long
/* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo
& /* _rShapeTreeInfo */)
807 OSL_FAIL("should not be called in the page preview");
811 ///===== Internal ========================================================
813 void ScShapeChildren::Init()
818 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
820 tools::Rectangle aPixelPaintRect
;
822 sal_uInt16
nCount(rData
.GetDrawRanges());
823 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
825 rData
.GetDrawRange(i
, aPixelPaintRect
, aMapMode
, nRangeId
);
826 FillShapes(aPixelPaintRect
, aMapMode
, nRangeId
);
830 sal_Int32
ScShapeChildren::GetBackShapeCount() const
833 for (auto const& shape
: maShapeRanges
)
834 nCount
+= shape
.maBackShapes
.size();
838 uno::Reference
<XAccessible
> ScShapeChildren::GetBackShape(sal_Int32 nIndex
) const
840 uno::Reference
<XAccessible
> xAccessible
;
841 for (const auto& rShapeRange
: maShapeRanges
)
843 sal_Int32
nCount(rShapeRange
.maBackShapes
.size());
845 xAccessible
= GetAccShape(rShapeRange
.maBackShapes
, nIndex
);
847 if (xAccessible
.is())
852 throw lang::IndexOutOfBoundsException();
857 sal_Int32
ScShapeChildren::GetForeShapeCount() const
860 for (auto const& shape
: maShapeRanges
)
861 nCount
+= shape
.maForeShapes
.size();
865 uno::Reference
<XAccessible
> ScShapeChildren::GetForeShape(sal_Int32 nIndex
) const
867 uno::Reference
<XAccessible
> xAccessible
;
868 for (const auto& rShapeRange
: maShapeRanges
)
870 sal_Int32
nCount(rShapeRange
.maForeShapes
.size());
872 xAccessible
= GetAccShape(rShapeRange
.maForeShapes
, nIndex
);
874 if (xAccessible
.is())
879 throw lang::IndexOutOfBoundsException();
884 sal_Int32
ScShapeChildren::GetControlCount() const
887 for (auto const& shape
: maShapeRanges
)
888 nCount
+= shape
.maControls
.size();
892 uno::Reference
<XAccessible
> ScShapeChildren::GetControl(sal_Int32 nIndex
) const
894 uno::Reference
<XAccessible
> xAccessible
;
895 for (const auto& rShapeRange
: maShapeRanges
)
897 sal_Int32
nCount(rShapeRange
.maControls
.size());
899 xAccessible
= GetAccShape(rShapeRange
.maControls
, nIndex
);
901 if (xAccessible
.is())
906 throw lang::IndexOutOfBoundsException();
913 struct ScShapePointFound
916 explicit ScShapePointFound(const awt::Point
& rPoint
) : maPoint(VCLPoint(rPoint
)) {}
917 bool operator() (const ScShapeChild
& rShape
)
920 if (VCLRectangle(rShape
.mpAccShape
->getBounds()).IsInside(maPoint
))
928 uno::Reference
<XAccessible
> ScShapeChildren::GetForegroundShapeAt(const awt::Point
& rPoint
) const //inclusive Controls
930 uno::Reference
<XAccessible
> xAcc
;
932 for(const auto& rShapeRange
: maShapeRanges
)
934 ScShapeChildVec::const_iterator aFindItr
= std::find_if(rShapeRange
.maForeShapes
.begin(), rShapeRange
.maForeShapes
.end(), ScShapePointFound(rPoint
));
935 if (aFindItr
!= rShapeRange
.maForeShapes
.end())
936 xAcc
= GetAccShape(*aFindItr
);
939 ScShapeChildVec::const_iterator aCtrlItr
= std::find_if(rShapeRange
.maControls
.begin(), rShapeRange
.maControls
.end(), ScShapePointFound(rPoint
));
940 if (aCtrlItr
!= rShapeRange
.maControls
.end())
941 xAcc
= GetAccShape(*aCtrlItr
);
951 uno::Reference
<XAccessible
> ScShapeChildren::GetBackgroundShapeAt(const awt::Point
& rPoint
) const
953 uno::Reference
<XAccessible
> xAcc
;
955 for(const auto& rShapeRange
: maShapeRanges
)
957 ScShapeChildVec::const_iterator aFindItr
= std::find_if(rShapeRange
.maBackShapes
.begin(), rShapeRange
.maBackShapes
.end(), ScShapePointFound(rPoint
));
958 if (aFindItr
!= rShapeRange
.maBackShapes
.end())
959 xAcc
= GetAccShape(*aFindItr
);
967 ::accessibility::AccessibleShape
* ScShapeChildren::GetAccShape(const ScShapeChild
& rShape
) const
969 if (!rShape
.mpAccShape
.is())
971 ::accessibility::ShapeTypeHandler
& rShapeHandler
= ::accessibility::ShapeTypeHandler::Instance();
972 ::accessibility::AccessibleShapeInfo
aShapeInfo(rShape
.mxShape
, mpAccDoc
);
976 ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo
;
977 aShapeTreeInfo
.SetSdrView(mpViewShell
->GetPreview()->GetDrawView());
978 aShapeTreeInfo
.SetController(nullptr);
979 aShapeTreeInfo
.SetDevice(mpViewShell
->GetWindow());
980 aShapeTreeInfo
.SetViewForwarder(&(maShapeRanges
[rShape
.mnRangeId
].maViewForwarder
));
981 rShape
.mpAccShape
= rShapeHandler
.CreateAccessibleObject(aShapeInfo
, aShapeTreeInfo
);
982 if (rShape
.mpAccShape
.is())
984 rShape
.mpAccShape
->Init();
988 return rShape
.mpAccShape
.get();
991 ::accessibility::AccessibleShape
* ScShapeChildren::GetAccShape(const ScShapeChildVec
& rShapes
, sal_Int32 nIndex
) const
993 return GetAccShape(rShapes
[nIndex
]);
996 void ScShapeChildren::FillShapes(const tools::Rectangle
& aPixelPaintRect
, const MapMode
& aMapMode
, sal_uInt8 nRangeId
)
998 OSL_ENSURE(nRangeId
< maShapeRanges
.size(), "this is not a valid range for draw objects");
999 SdrPage
* pPage
= GetDrawPage();
1000 vcl::Window
* pWin
= mpViewShell
->GetWindow();
1001 if (!(pPage
&& pWin
))
1004 bool bForeAdded(false);
1005 bool bBackAdded(false);
1006 bool bControlAdded(false);
1007 tools::Rectangle
aClippedPixelPaintRect(aPixelPaintRect
);
1010 tools::Rectangle
aRect2(Point(0,0), mpAccDoc
->GetBoundingBoxOnScreen().GetSize());
1011 aClippedPixelPaintRect
= aPixelPaintRect
.GetIntersection(aRect2
);
1013 ScIAccessibleViewForwarder
aViewForwarder(mpViewShell
, mpAccDoc
, aMapMode
);
1014 maShapeRanges
[nRangeId
].maViewForwarder
= aViewForwarder
;
1015 const size_t nCount(pPage
->GetObjCount());
1016 for (size_t i
= 0; i
< nCount
; ++i
)
1018 SdrObject
* pObj
= pPage
->GetObj(i
);
1021 uno::Reference
< drawing::XShape
> xShape(pObj
->getUnoShape(), uno::UNO_QUERY
);
1024 tools::Rectangle
aRect(pWin
->LogicToPixel(VCLPoint(xShape
->getPosition()), aMapMode
), pWin
->LogicToPixel(VCLSize(xShape
->getSize()), aMapMode
));
1025 if(!aClippedPixelPaintRect
.GetIntersection(aRect
).IsEmpty())
1027 ScShapeChild aShape
;
1028 aShape
.mxShape
= xShape
;
1029 aShape
.mnRangeId
= nRangeId
;
1030 if (pObj
->GetLayer().anyOf(SC_LAYER_INTERN
, SC_LAYER_FRONT
))
1032 maShapeRanges
[nRangeId
].maForeShapes
.push_back(std::move(aShape
));
1035 else if (pObj
->GetLayer() == SC_LAYER_BACK
)
1037 maShapeRanges
[nRangeId
].maBackShapes
.push_back(std::move(aShape
));
1040 else if (pObj
->GetLayer() == SC_LAYER_CONTROLS
)
1042 maShapeRanges
[nRangeId
].maControls
.push_back(std::move(aShape
));
1043 bControlAdded
= true;
1047 OSL_FAIL("I don't know this layer.");
1054 std::sort(maShapeRanges
[nRangeId
].maForeShapes
.begin(), maShapeRanges
[nRangeId
].maForeShapes
.end(),ScShapeChildLess());
1056 std::sort(maShapeRanges
[nRangeId
].maBackShapes
.begin(), maShapeRanges
[nRangeId
].maBackShapes
.end(),ScShapeChildLess());
1058 std::sort(maShapeRanges
[nRangeId
].maControls
.begin(), maShapeRanges
[nRangeId
].maControls
.end(),ScShapeChildLess());
1061 SdrPage
* ScShapeChildren::GetDrawPage() const
1063 SCTAB
nTab( mpViewShell
->GetLocationData().GetPrintTab() );
1064 SdrPage
* pDrawPage
= nullptr;
1065 ScDocument
& rDoc
= mpViewShell
->GetDocument();
1066 if (rDoc
.GetDrawLayer())
1068 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
1069 if (pDrawLayer
->HasObjects() && (pDrawLayer
->GetPageCount() > nTab
))
1070 pDrawPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(static_cast<sal_Int16
>(nTab
)));
1077 struct ScPagePreviewCountData
1079 // order is background shapes, header, table or notes, footer, foreground shapes, controls
1081 tools::Rectangle aVisRect
;
1082 tools::Long nBackShapes
;
1083 tools::Long nHeaders
;
1084 tools::Long nTables
;
1085 tools::Long nNoteParagraphs
;
1086 tools::Long nFooters
;
1087 tools::Long nForeShapes
;
1088 tools::Long nControls
;
1090 ScPagePreviewCountData( const ScPreviewLocationData
& rData
, const vcl::Window
* pSizeWindow
,
1091 const ScNotesChildren
* pNotesChildren
, const ScShapeChildren
* pShapeChildren
);
1093 tools::Long
GetTotal() const
1095 return nBackShapes
+ nHeaders
+ nTables
+ nNoteParagraphs
+ nFooters
+ nForeShapes
+ nControls
;
1101 ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData
& rData
,
1102 const vcl::Window
* pSizeWindow
, const ScNotesChildren
* pNotesChildren
,
1103 const ScShapeChildren
* pShapeChildren
) :
1107 nNoteParagraphs( 0 ),
1114 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1115 aVisRect
= tools::Rectangle( Point(), aOutputSize
);
1117 tools::Rectangle aObjRect
;
1119 if ( rData
.GetHeaderPosition( aObjRect
) && aObjRect
.IsOver( aVisRect
) )
1122 if ( rData
.GetFooterPosition( aObjRect
) && aObjRect
.IsOver( aVisRect
) )
1125 if ( rData
.HasCellsInRange( aVisRect
) )
1129 nBackShapes
= pShapeChildren
->GetBackShapeCount();
1130 nForeShapes
= pShapeChildren
->GetForeShapeCount();
1131 nControls
= pShapeChildren
->GetControlCount();
1133 // there are only notes if there is no table
1135 nNoteParagraphs
= pNotesChildren
->GetChildrenCount();
1138 //===== internal ========================================================
1140 ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
1141 const uno::Reference
<XAccessible
>& rxParent
, ScPreviewShell
* pViewShell
) :
1142 ScAccessibleDocumentBase(rxParent
),
1143 mpViewShell(pViewShell
)
1146 pViewShell
->AddAccessibilityObject(*this);
1150 ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview()
1152 if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper
.bInDispose
)
1154 // increment refcount to prevent double call off dtor
1155 osl_atomic_increment( &m_refCount
);
1156 // call dispose to inform object which have a weak reference to this object
1161 void SAL_CALL
ScAccessibleDocumentPagePreview::disposing()
1163 SolarMutexGuard aGuard
;
1170 mpViewShell
->RemoveAccessibilityObject(*this);
1171 mpViewShell
= nullptr;
1174 // no need to Dispose the AccessibleTextHelper,
1175 // as long as mpNotesChildren are destructed here
1176 mpNotesChildren
.reset();
1178 mpShapeChildren
.reset();
1180 ScAccessibleDocumentBase::disposing();
1183 //===== SfxListener =====================================================
1185 void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1187 if ( dynamic_cast<const ScAccWinFocusLostHint
*>(&rHint
) )
1191 else if ( dynamic_cast<const ScAccWinFocusGotHint
*>(&rHint
) )
1193 CommitFocusGained();
1197 // only notify if child exist, otherwise it is not necessary
1198 if (rHint
.GetId() == SfxHintId::ScDataChanged
)
1200 if (mpTable
.is()) // if there is no table there is nothing to notify, because no one recognizes the change
1203 uno::Reference
<XAccessible
> xAcc
= mpTable
.get();
1204 AccessibleEventObject aEvent
;
1205 aEvent
.EventId
= AccessibleEventId::CHILD
;
1206 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1207 aEvent
.OldValue
<<= xAcc
;
1208 CommitChange(aEvent
);
1216 vcl::Window
* pSizeWindow
= mpViewShell
->GetWindow();
1218 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1219 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1220 GetNotesChildren()->DataChanged(aVisRect
);
1222 GetShapeChildren()->DataChanged();
1224 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1225 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1227 if (aCount
.nTables
> 0)
1229 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1230 sal_Int32
nIndex (aCount
.nBackShapes
+ aCount
.nHeaders
);
1232 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1236 uno::Reference
<XAccessible
> xAcc
= mpTable
.get();
1237 AccessibleEventObject aEvent
;
1238 aEvent
.EventId
= AccessibleEventId::CHILD
;
1239 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1240 aEvent
.NewValue
<<= xAcc
;
1241 CommitChange(aEvent
);
1245 else if (rHint
.GetId() == SfxHintId::ScAccVisAreaChanged
)
1248 vcl::Window
* pSizeWindow
= mpViewShell
->GetWindow();
1250 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1251 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1252 GetNotesChildren()->DataChanged(aVisRect
);
1254 GetShapeChildren()->VisAreaChanged();
1256 AccessibleEventObject aEvent
;
1257 aEvent
.EventId
= AccessibleEventId::VISIBLE_DATA_CHANGED
;
1258 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1259 CommitChange(aEvent
);
1262 ScAccessibleDocumentBase::Notify(rBC
, rHint
);
1265 //===== XAccessibleComponent ============================================
1267 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point
& rPoint
)
1269 uno::Reference
<XAccessible
> xAccessible
;
1270 if (containsPoint(rPoint
))
1272 SolarMutexGuard aGuard
;
1277 xAccessible
= GetShapeChildren()->GetForegroundShapeAt(rPoint
);
1278 if (!xAccessible
.is())
1280 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1281 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1283 if ( !mpTable
.is() && (aCount
.nTables
> 0) )
1285 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1286 sal_Int32
nIndex (aCount
.nBackShapes
+ aCount
.nHeaders
);
1288 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1291 if (mpTable
.is() && VCLRectangle(mpTable
->getBounds()).IsInside(VCLPoint(rPoint
)))
1292 xAccessible
= mpTable
.get();
1294 if (!xAccessible
.is())
1295 xAccessible
= GetNotesChildren()->GetAt(rPoint
);
1296 if (!xAccessible
.is())
1298 if (!mpHeader
.is() || !mpFooter
.is())
1300 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1301 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1305 mpHeader
= new ScAccessiblePageHeader( this, mpViewShell
, true, aCount
.nBackShapes
+ aCount
.nHeaders
- 1);
1309 mpFooter
= new ScAccessiblePageHeader( this, mpViewShell
, false, aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
- 1 );
1313 Point
aPoint(VCLPoint(rPoint
));
1315 if (VCLRectangle(mpHeader
->getBounds()).IsInside(aPoint
))
1316 xAccessible
= mpHeader
.get();
1317 else if (VCLRectangle(mpFooter
->getBounds()).IsInside(aPoint
))
1318 xAccessible
= mpFooter
.get();
1320 if (!xAccessible
.is())
1321 xAccessible
= GetShapeChildren()->GetBackgroundShapeAt(rPoint
);
1328 void SAL_CALL
ScAccessibleDocumentPagePreview::grabFocus()
1330 SolarMutexGuard aGuard
;
1332 if (getAccessibleParent().is())
1334 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
1335 if (xAccessibleComponent
.is())
1337 // just grab the focus for the window
1338 xAccessibleComponent
->grabFocus();
1343 //===== XAccessibleContext ==============================================
1345 sal_Int32 SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleChildCount()
1347 SolarMutexGuard aGuard
;
1350 tools::Long nRet
= 0;
1353 ScPagePreviewCountData
aCount( mpViewShell
->GetLocationData(), mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1354 nRet
= aCount
.GetTotal();
1360 uno::Reference
<XAccessible
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex
)
1362 SolarMutexGuard aGuard
;
1364 uno::Reference
<XAccessible
> xAccessible
;
1368 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1369 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1371 if ( nIndex
< aCount
.nBackShapes
)
1373 xAccessible
= GetShapeChildren()->GetBackShape(nIndex
);
1375 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
)
1377 if ( !mpHeader
.is() )
1379 mpHeader
= new ScAccessiblePageHeader( this, mpViewShell
, true, nIndex
);
1382 xAccessible
= mpHeader
.get();
1384 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
)
1386 if ( !mpTable
.is() )
1388 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1391 xAccessible
= mpTable
.get();
1393 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nNoteParagraphs
)
1395 xAccessible
= GetNotesChildren()->GetChild(nIndex
- aCount
.nBackShapes
- aCount
.nHeaders
);
1397 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
)
1399 if ( !mpFooter
.is() )
1401 mpFooter
= new ScAccessiblePageHeader( this, mpViewShell
, false, nIndex
);
1403 xAccessible
= mpFooter
.get();
1407 sal_Int32
nIdx(nIndex
- (aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
));
1408 if (nIdx
< aCount
.nForeShapes
)
1409 xAccessible
= GetShapeChildren()->GetForeShape(nIdx
);
1411 xAccessible
= GetShapeChildren()->GetControl(nIdx
- aCount
.nForeShapes
);
1415 if ( !xAccessible
.is() )
1416 throw lang::IndexOutOfBoundsException();
1421 /// Return the set of current states.
1422 uno::Reference
<XAccessibleStateSet
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleStateSet()
1424 SolarMutexGuard aGuard
;
1425 uno::Reference
<XAccessibleStateSet
> xParentStates
;
1426 if (getAccessibleParent().is())
1428 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
1429 xParentStates
= xParentContext
->getAccessibleStateSet();
1431 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
1432 if (IsDefunc(xParentStates
))
1433 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
1437 pStateSet
->AddState(AccessibleStateType::ENABLED
);
1438 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
1440 pStateSet
->AddState(AccessibleStateType::SHOWING
);
1442 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
1447 //===== XServiceInfo ====================================================
1449 OUString SAL_CALL
ScAccessibleDocumentPagePreview::getImplementationName()
1451 return "ScAccessibleDocumentPagePreview";
1454 uno::Sequence
< OUString
> SAL_CALL
ScAccessibleDocumentPagePreview::getSupportedServiceNames()
1456 uno::Sequence
< OUString
> aSequence
= ScAccessibleContextBase::getSupportedServiceNames();
1457 sal_Int32
nOldSize(aSequence
.getLength());
1458 aSequence
.realloc(nOldSize
+ 1);
1460 aSequence
[nOldSize
] = "com.sun.star.AccessibleSpreadsheetPageView";
1465 //===== XTypeProvider =======================================================
1467 uno::Sequence
<sal_Int8
> SAL_CALL
1468 ScAccessibleDocumentPagePreview::getImplementationId()
1470 return css::uno::Sequence
<sal_Int8
>();
1473 //===== internal ========================================================
1475 OUString
ScAccessibleDocumentPagePreview::createAccessibleDescription()
1477 return STR_ACC_PREVIEWDOC_DESCR
;
1480 OUString
ScAccessibleDocumentPagePreview::createAccessibleName()
1482 OUString sName
= ScResId(STR_ACC_PREVIEWDOC_NAME
);
1486 tools::Rectangle
ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const
1488 tools::Rectangle aRect
;
1491 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1493 aRect
= pWindow
->GetWindowExtentsRelative(nullptr);
1498 tools::Rectangle
ScAccessibleDocumentPagePreview::GetBoundingBox() const
1500 tools::Rectangle aRect
;
1503 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1505 aRect
= pWindow
->GetWindowExtentsRelative(pWindow
->GetAccessibleParentWindow());
1510 bool ScAccessibleDocumentPagePreview::IsDefunc(
1511 const uno::Reference
<XAccessibleStateSet
>& rxParentStates
)
1513 return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
1514 (rxParentStates
.is() && rxParentStates
->contains(AccessibleStateType::DEFUNC
));
1517 ScNotesChildren
* ScAccessibleDocumentPagePreview::GetNotesChildren()
1519 if (!mpNotesChildren
&& mpViewShell
)
1521 mpNotesChildren
.reset( new ScNotesChildren(mpViewShell
, this) );
1523 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1524 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1526 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1527 mpNotesChildren
->Init(aCount
.aVisRect
, aCount
.nBackShapes
+ aCount
.nHeaders
);
1529 return mpNotesChildren
.get();
1532 ScShapeChildren
* ScAccessibleDocumentPagePreview::GetShapeChildren()
1534 if (!mpShapeChildren
&& mpViewShell
)
1536 mpShapeChildren
.reset( new ScShapeChildren(mpViewShell
, this) );
1537 mpShapeChildren
->Init();
1540 return mpShapeChildren
.get();
1543 OUString
ScAccessibleDocumentPagePreview::getAccessibleName()
1547 OUString aName
= ScResId(STR_ACC_DOC_SPREADSHEET
);
1548 ScDocument
& rScDoc
= mpViewShell
->GetDocument();
1550 SfxObjectShell
* pObjSh
= rScDoc
.GetDocumentShell();
1555 SfxMedium
* pMed
= pObjSh
->GetMedium();
1557 aFileName
= pMed
->GetName();
1559 if (aFileName
.isEmpty())
1560 aFileName
= pObjSh
->GetTitle(SFX_TITLE_APINAME
);
1562 if (!aFileName
.isEmpty())
1564 aName
= aFileName
+ " - " + aName
+ ScResId(STR_ACC_DOC_PREVIEW_SUFFIX
);
1571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */