LibreOffice Module sc (master) 1
AccessibleDocumentPagePreview.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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>
34#include <postit.hxx>
35
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
41#include <tools/gen.hxx>
42#include <svx/fmview.hxx>
43#include <svx/svdpage.hxx>
44#include <svx/svdobj.hxx>
52#include <vcl/svapp.hxx>
53#include <sfx2/docfile.hxx>
54
55#include <vector>
56#include <algorithm>
57#include <memory>
58#include <utility>
59
60using namespace ::com::sun::star;
61using namespace ::com::sun::star::accessibility;
62
63typedef std::vector< uno::Reference< XAccessible > > ScXAccVector;
64
65namespace {
66
67struct ScAccNote
68{
69 OUString maNoteText;
70 tools::Rectangle maRect;
71 ScAddress maNoteCell;
73 sal_Int32 mnParaCount;
74 bool mbMarkNote;
75
76 ScAccNote()
77 : mpTextHelper(nullptr)
78 , mnParaCount(0)
79 , mbMarkNote(false)
80 {
81 }
82};
83
84}
85
87{
88public:
91 void Init(const tools::Rectangle& rVisRect, sal_Int32 nOffset);
92
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;
96
97 void DataChanged(const tools::Rectangle& rVisRect);
98
99private:
102 typedef std::vector<ScAccNote> ScAccNotes;
105 sal_Int32 mnParagraphs;
106 sal_Int32 mnOffset;
107
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);
110
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);
116
117 inline ScDocument* GetDocument() const;
118};
119
121 : mpViewShell(pViewShell),
122 mpAccDoc(pAccDoc),
123 mnParagraphs(0),
124 mnOffset(0)
125{
126}
127
129{
130 for (auto & i : maNotes)
131 if (i.mpTextHelper)
132 {
133 delete i.mpTextHelper;
134 i.mpTextHelper = nullptr;
135 }
136 for (auto & i : maMarks)
137 if (i.mpTextHelper)
138 {
139 delete i.mpTextHelper;
140 i.mpTextHelper = nullptr;
141 }
142}
143
144::accessibility::AccessibleTextHelper* ScNotesChildren::CreateTextHelper(const OUString& rString, const tools::Rectangle& rVisRect, const ScAddress& aCellPos, bool bMarkNote, sal_Int32 nChildOffset) const
145{
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());
150
151 return pTextHelper;
152}
153
154sal_Int32 ScNotesChildren::AddNotes(const ScPreviewLocationData& rData, const tools::Rectangle& rVisRect, bool bMark, ScAccNotes& rNotes)
155{
156 sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
157
158 rNotes.reserve(nCount);
159
160 sal_Int32 nParagraphs(0);
161 ScDocument* pDoc = GetDocument();
162 if (pDoc)
163 {
164 ScAccNote aNote;
165 aNote.mbMarkNote = bMark;
166 if (bMark)
167 aNote.mnParaCount = 1;
168 for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
169 {
170 if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
171 {
172 if (bMark)
173 {
174 // Document not needed, because only the cell address, but not the tablename is needed
175 aNote.maNoteText = aNote.maNoteCell.Format(ScRefFlags::VALID);
176 }
177 else
178 {
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();
184 }
185 nParagraphs += aNote.mnParaCount;
186 rNotes.push_back(aNote);
187 }
188 }
189 }
190 return nParagraphs;
191}
192
193void ScNotesChildren::Init(const tools::Rectangle& rVisRect, sal_Int32 nOffset)
194{
196 {
197 mnOffset = nOffset;
199
200 mnParagraphs = AddNotes(rData, rVisRect, false, maMarks);
201 mnParagraphs += AddNotes(rData, rVisRect, true, maNotes);
202 }
203}
204
205namespace {
206
207struct ScParaFound
208{
209 sal_Int32 mnIndex;
210 explicit ScParaFound(sal_Int32 nIndex) : mnIndex(nIndex) {}
211 bool operator() (const ScAccNote& rNote)
212 {
213 bool bResult(false);
214 if (rNote.mnParaCount > mnIndex)
215 bResult = true;
216 else
217 mnIndex -= rNote.mnParaCount;
218 return bResult;
219 }
220};
221
222}
223
224uno::Reference<XAccessible> ScNotesChildren::GetChild(sal_Int32 nIndex) const
225{
226 uno::Reference<XAccessible> xAccessible;
227
228 if (nIndex < mnParagraphs)
229 {
230 if (nIndex < static_cast<sal_Int32>(maMarks.size()))
231 {
232 ScAccNotes::iterator aEndItr = maMarks.end();
233 ScParaFound aParaFound(nIndex);
234 ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aParaFound);
235 if (aItr != aEndItr)
236 {
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());
241 }
242 else
243 {
244 OSL_FAIL("wrong note found");
245 }
246 }
247 else
248 {
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);
253 if (aEndItr != aItr)
254 {
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());
258 }
259 }
260 }
261
262 return xAccessible;
263}
264
265namespace {
266
267struct ScPointFound
268{
270 sal_Int32 mnParagraphs;
271 explicit ScPointFound(const Point& rPoint) : maPoint(rPoint, Size(0, 0)), mnParagraphs(0) {}
272 bool operator() (const ScAccNote& rNote)
273 {
274 bool bResult(false);
275 if (maPoint.Contains(rNote.maRect))
276 bResult = true;
277 else
278 mnParagraphs += rNote.mnParaCount;
279 return bResult;
280 }
281};
282
283}
284
285uno::Reference<XAccessible> ScNotesChildren::GetAt(const awt::Point& rPoint) const
286{
287 uno::Reference<XAccessible> xAccessible;
288
289 ScPointFound aPointFound(Point(rPoint.X, rPoint.Y));
290
291 ScAccNotes::iterator aEndItr = maMarks.end();
292 ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aPointFound);
293 if (aEndItr == aItr)
294 {
295 aEndItr = maNotes.end();
296 aItr = std::find_if(maNotes.begin(), aEndItr, aPointFound);
297 }
298 if (aEndItr != aItr)
299 {
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);
303 }
304
305 return xAccessible;
306}
307
309{
310 OSL_ENSURE(aCell1.Tab() == aCell2.Tab(), "the notes should be on the same table");
311 sal_Int8 nResult(0);
312 if (aCell1 != aCell2)
313 {
314 if (aCell1.Row() == aCell2.Row())
315 nResult = (aCell1.Col() < aCell2.Col()) ? -1 : 1;
316 else
317 nResult = (aCell1.Row() < aCell2.Row()) ? -1 : 1;
318 }
319 return nResult;
320}
321
322void ScNotesChildren::CollectChildren(const ScAccNote& rNote, ScXAccVector& rVector)
323{
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()));
327}
328
330 const tools::Rectangle& rVisRect, bool bMark, ScAccNotes& rOldNotes,
331 ScAccNotes& rNewNotes, ScXAccVector& rOldParas, ScXAccVector& rNewParas)
332{
333 sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
334
335 rNewNotes.reserve(nCount);
336
337 sal_Int32 nParagraphs(0);
338 ScDocument* pDoc = GetDocument();
339 if (pDoc)
340 {
341 ScAccNote aNote;
342 aNote.mbMarkNote = bMark;
343 if (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)
349 {
350 if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
351 {
352 if (bMark)
353 {
354 // Document not needed, because only the cell address, but not the tablename is needed
355 aNote.maNoteText = aNote.maNoteCell.Format(ScRefFlags::VALID);
356 }
357 else
358 {
359 if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
360 aNote.maNoteText = pNote->GetText();
361 }
362
363 sal_Int8 nCompare(-1); // if there are no more old children it is always a new one
364 if (aItr != aEndItr)
365 nCompare = CompareCell(aNote.maNoteCell, aItr->maNoteCell);
366 if (nCompare == 0)
367 {
368 if (aNote.maNoteText == aItr->maNoteText)
369 {
370 aNote.mpTextHelper = aItr->mpTextHelper;
371 if (aNote.maRect != aItr->maRect) // set new VisArea
372 {
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
377 }
378 }
379 else
380 {
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);
390 }
391 bAddNote = true;
392 // not necessary, because this branch should not be reached if it is the end
393 //if (aItr != aEndItr)
394 ++aItr;
395 }
396 else if (nCompare < 0)
397 {
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);
403 bAddNote = true;
404 }
405 else
406 {
407 // collect removed children
408 CollectChildren(*aItr, rOldParas);
409 delete aItr->mpTextHelper;
410 aItr->mpTextHelper = nullptr;
411
412 // no note to add
413 // not necessary, because this branch should not be reached if it is the end
414 //if (aItr != aEndItr)
415 ++aItr;
416 }
417 if (bAddNote)
418 {
419 nParagraphs += aNote.mnParaCount;
420 rNewNotes.push_back(aNote);
421 bAddNote = false;
422 }
423 }
424 }
425 }
426 return nParagraphs;
427}
428
429namespace {
430
431struct ScChildGone
432{
434 explicit ScChildGone(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
435 void operator() (const uno::Reference<XAccessible>& xAccessible) const
436 {
437 if (mpAccDoc)
438 {
439 AccessibleEventObject aEvent;
440 aEvent.EventId = AccessibleEventId::CHILD;
441 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
442 aEvent.OldValue <<= xAccessible;
443 aEvent.IndexHint = -1;
444
445 mpAccDoc->CommitChange(aEvent); // gone child - event
446 }
447 }
448};
449
450struct ScChildNew
451{
453 explicit ScChildNew(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
454 void operator() (const uno::Reference<XAccessible>& xAccessible) const
455 {
456 if (mpAccDoc)
457 {
458 AccessibleEventObject aEvent;
459 aEvent.EventId = AccessibleEventId::CHILD;
460 aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
461 aEvent.NewValue <<= xAccessible;
462 aEvent.IndexHint = -1;
463
464 mpAccDoc->CommitChange(aEvent); // new child - event
465 }
466 }
467};
468
469}
470
472{
473 if (!(mpViewShell && mpAccDoc))
474 return;
475
476 ScXAccVector aNewParas;
477 ScXAccVector aOldParas;
478 ScAccNotes aNewMarks;
479 mnParagraphs = CheckChanges(mpViewShell->GetLocationData(), rVisRect, true, maMarks, aNewMarks, aOldParas, aNewParas);
480 maMarks = aNewMarks;
481 ScAccNotes aNewNotes;
482 mnParagraphs += CheckChanges(mpViewShell->GetLocationData(), rVisRect, false, maNotes, aNewNotes, aOldParas, aNewParas);
483 maNotes = aNewNotes;
484
485 std::for_each(aOldParas.begin(), aOldParas.end(), ScChildGone(mpAccDoc));
486 std::for_each(aNewParas.begin(), aNewParas.end(), ScChildNew(mpAccDoc));
487}
488
490{
491 ScDocument* pDoc = nullptr;
492 if (mpViewShell)
493 pDoc = &mpViewShell->GetDocument();
494 return pDoc;
495}
496
497namespace {
498
499class ScIAccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder
500{
501public:
502 ScIAccessibleViewForwarder();
503 ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
505 const MapMode& aMapMode);
506
508
509 virtual tools::Rectangle GetVisibleArea() const override;
510 virtual Point LogicToPixel (const Point& rPoint) const override;
511 virtual Size LogicToPixel (const Size& rSize) const override;
512
513private:
514 ScPreviewShell* mpViewShell;
516 MapMode maMapMode;
517};
518
519}
520
521ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
522 : mpViewShell(nullptr), mpAccDoc(nullptr)
523{
524}
525
526ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
528 const MapMode& aMapMode)
529 : mpViewShell(pViewShell),
530 mpAccDoc(pAccDoc),
531 maMapMode(aMapMode)
532{
533}
534
536
537tools::Rectangle ScIAccessibleViewForwarder::GetVisibleArea() const
538{
539 SolarMutexGuard aGuard;
540 tools::Rectangle aVisRect;
541 vcl::Window* pWin = mpViewShell->GetWindow();
542 if (pWin)
543 {
544 aVisRect.SetSize(pWin->GetOutputSizePixel());
545 aVisRect.SetPos(Point(0, 0));
546
547 aVisRect = pWin->PixelToLogic(aVisRect, maMapMode);
548 }
549
550 return aVisRect;
551}
552
553Point ScIAccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
554{
555 SolarMutexGuard aGuard;
556 Point aPoint;
557 vcl::Window* pWin = mpViewShell->GetWindow();
558 if (pWin && mpAccDoc)
559 {
560 tools::Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
561 aPoint = pWin->LogicToPixel(rPoint, maMapMode) + aRect.TopLeft();
562 }
563
564 return aPoint;
565}
566
567Size ScIAccessibleViewForwarder::LogicToPixel (const Size& rSize) const
568{
569 SolarMutexGuard aGuard;
570 Size aSize;
571 vcl::Window* pWin = mpViewShell->GetWindow();
572 if (pWin)
573 aSize = pWin->LogicToPixel(rSize, maMapMode);
574 return aSize;
575}
576
577namespace {
578
579struct ScShapeChild
580{
581 ScShapeChild()
582 : mnRangeId(0)
583 {
584 }
585 ScShapeChild(ScShapeChild const &) = delete;
586 ScShapeChild(ScShapeChild &&) = default;
587 ~ScShapeChild();
588 ScShapeChild & operator =(ScShapeChild const &) = delete;
589 ScShapeChild & operator =(ScShapeChild && other) {
590 std::swap(mpAccShape, other.mpAccShape);
591 mxShape = std::move(other.mxShape);
592 mnRangeId = other.mnRangeId;
593 return *this;
594 }
595
597 css::uno::Reference< css::drawing::XShape > mxShape;
598 sal_Int32 mnRangeId;
599};
600
601}
602
603ScShapeChild::~ScShapeChild()
604{
605 if (mpAccShape.is())
606 {
607 mpAccShape->dispose();
608 }
609}
610
611namespace {
612
613struct ScShapeChildLess
614{
615 bool operator()(const ScShapeChild& rChild1, const ScShapeChild& rChild2) const
616 {
617 bool bResult(false);
618 if (rChild1.mxShape.is() && rChild2.mxShape.is())
619 bResult = (rChild1.mxShape.get() < rChild2.mxShape.get());
620 return bResult;
621 }
622};
623
624}
625
626typedef std::vector<ScShapeChild> ScShapeChildVec;
627
628namespace {
629
630struct ScShapeRange
631{
632 ScShapeRange() = default;
633 ScShapeRange(ScShapeRange const &) = delete;
634 ScShapeRange(ScShapeRange &&) = default;
635 ScShapeRange & operator =(ScShapeRange const &) = delete;
636 ScShapeRange & operator =(ScShapeRange &&) = default;
637
638 ScShapeChildVec maBackShapes;
639 ScShapeChildVec maForeShapes; // inclusive internal shapes
640 ScShapeChildVec maControls;
641 ScIAccessibleViewForwarder maViewForwarder;
642};
643
644}
645
646typedef std::vector<ScShapeRange> ScShapeRangeVec;
647
649{
650public:
652
654
655 virtual bool ReplaceChild (
657 const css::uno::Reference< css::drawing::XShape >& _rxShape,
658 const tools::Long _nIndex,
659 const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
660 ) override;
661
663
664 void Init();
665
666 sal_Int32 GetBackShapeCount() const;
667 uno::Reference<XAccessible> GetBackShape(sal_Int32 nIndex) const;
668 sal_Int32 GetForeShapeCount() const;
669 uno::Reference<XAccessible> GetForeShape(sal_Int32 nIndex) const;
670 sal_Int32 GetControlCount() const;
671 uno::Reference<XAccessible> GetControl(sal_Int32 nIndex) const;
672 uno::Reference<XAccessible> GetForegroundShapeAt(const awt::Point& rPoint) const; // inclusive controls
673 uno::Reference<XAccessible> GetBackgroundShapeAt(const awt::Point& rPoint) const;
674
675 void DataChanged();
676 void VisAreaChanged() const;
677
678private:
682
683 void FindChanged(ScShapeChildVec& aOld, ScShapeChildVec& aNew) const;
684 void FindChanged(ScShapeRange& aOld, ScShapeRange& aNew) const;
685 ::accessibility::AccessibleShape* GetAccShape(const ScShapeChild& rShape) const;
686 ::accessibility::AccessibleShape* GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const;
687 void FillShapes(const tools::Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId);
688
689// void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
690// void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
691 SdrPage* GetDrawPage() const;
692};
693
695 :
696 mpAccDoc(pAccDoc),
697 mpViewShell(pViewShell),
698 maShapeRanges(SC_PREVIEW_MAXRANGES)
699{
700}
701
703{
704 ScShapeChildVec::iterator aOldItr = rOld.begin();
705 ScShapeChildVec::iterator aOldEnd = rOld.end();
706 ScShapeChildVec::const_iterator aNewItr = rNew.begin();
707 ScShapeChildVec::const_iterator aNewEnd = rNew.end();
708 uno::Reference<XAccessible> xAcc;
709 while ((aNewItr != aNewEnd) && (aOldItr != aOldEnd))
710 {
711 if (aNewItr->mxShape.get() == aOldItr->mxShape.get())
712 {
713 ++aOldItr;
714 ++aNewItr;
715 }
716 else if (aNewItr->mxShape.get() < aOldItr->mxShape.get())
717 {
718 xAcc = GetAccShape(*aNewItr);
719 AccessibleEventObject aEvent;
720 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
721 aEvent.EventId = AccessibleEventId::CHILD;
722 aEvent.NewValue <<= xAcc;
723 aEvent.IndexHint = -1;
725 ++aNewItr;
726 }
727 else
728 {
729 xAcc = GetAccShape(*aOldItr);
730 AccessibleEventObject aEvent;
731 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
732 aEvent.EventId = AccessibleEventId::CHILD;
733 aEvent.OldValue <<= xAcc;
734 aEvent.IndexHint = -1;
736 ++aOldItr;
737 }
738 }
739 while (aOldItr != aOldEnd)
740 {
741 xAcc = GetAccShape(*aOldItr);
742 AccessibleEventObject aEvent;
743 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
744 aEvent.EventId = AccessibleEventId::CHILD;
745 aEvent.OldValue <<= xAcc;
746 aEvent.IndexHint = -1;
748 ++aOldItr;
749 }
750 while (aNewItr != aNewEnd)
751 {
752 xAcc = GetAccShape(*aNewItr);
753 AccessibleEventObject aEvent;
754 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
755 aEvent.EventId = AccessibleEventId::CHILD;
756 aEvent.NewValue <<= xAcc;
757 aEvent.IndexHint = -1;
759 ++aNewItr;
760 }
761}
762
763void ScShapeChildren::FindChanged(ScShapeRange& rOld, ScShapeRange& rNew) const
764{
765 FindChanged(rOld.maBackShapes, rNew.maBackShapes);
766 FindChanged(rOld.maForeShapes, rNew.maForeShapes);
767 FindChanged(rOld.maControls, rNew.maControls);
768}
769
771{
772 ScShapeRangeVec aOldShapeRanges(std::move(maShapeRanges));
773 maShapeRanges.clear();
775 Init();
776 for (sal_Int32 i = 0; i < SC_PREVIEW_MAXRANGES; ++i)
777 {
778 FindChanged(aOldShapeRanges[i], maShapeRanges[i]);
779 }
780}
781
782namespace
783{
784 struct ScVisAreaChanged
785 {
786 void operator() (const ScShapeChild& rAccShapeData) const
787 {
788 if (rAccShapeData.mpAccShape.is())
789 {
790 rAccShapeData.mpAccShape->ViewForwarderChanged();
791 }
792 }
793 };
794}
795
797{
798 for (auto const& shape : maShapeRanges)
799 {
800 ScVisAreaChanged aVisAreaChanged;
801 std::for_each(shape.maBackShapes.begin(), shape.maBackShapes.end(), aVisAreaChanged);
802 std::for_each(shape.maControls.begin(), shape.maControls.end(), aVisAreaChanged);
803 std::for_each(shape.maForeShapes.begin(), shape.maForeShapes.end(), aVisAreaChanged);
804 }
805}
806
808
810 const css::uno::Reference< css::drawing::XShape >& /* _rxShape */,
811 const tools::Long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo& /* _rShapeTreeInfo */)
812{
813 OSL_FAIL("should not be called in the page preview");
814 return false;
815}
816
818
820{
821 if(!mpViewShell)
822 return;
823
825 MapMode aMapMode;
826 tools::Rectangle aPixelPaintRect;
827 sal_uInt8 nRangeId;
828 sal_uInt16 nCount(rData.GetDrawRanges());
829 for (sal_uInt16 i = 0; i < nCount; ++i)
830 {
831 rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId);
832 FillShapes(aPixelPaintRect, aMapMode, nRangeId);
833 }
834}
835
837{
838 sal_Int32 nCount(0);
839 for (auto const& shape : maShapeRanges)
840 nCount += shape.maBackShapes.size();
841 return nCount;
842}
843
844uno::Reference<XAccessible> ScShapeChildren::GetBackShape(sal_Int32 nIndex) const
845{
846 uno::Reference<XAccessible> xAccessible;
847 for (const auto& rShapeRange : maShapeRanges)
848 {
849 sal_Int32 nCount(rShapeRange.maBackShapes.size());
850 if(nIndex < nCount)
851 xAccessible = GetAccShape(rShapeRange.maBackShapes, nIndex);
852 nIndex -= nCount;
853 if (xAccessible.is())
854 break;
855 }
856
857 if (nIndex >= 0)
858 throw lang::IndexOutOfBoundsException();
859
860 return xAccessible;
861}
862
864{
865 sal_Int32 nCount(0);
866 for (auto const& shape : maShapeRanges)
867 nCount += shape.maForeShapes.size();
868 return nCount;
869}
870
871uno::Reference<XAccessible> ScShapeChildren::GetForeShape(sal_Int32 nIndex) const
872{
873 uno::Reference<XAccessible> xAccessible;
874 for (const auto& rShapeRange : maShapeRanges)
875 {
876 sal_Int32 nCount(rShapeRange.maForeShapes.size());
877 if(nIndex < nCount)
878 xAccessible = GetAccShape(rShapeRange.maForeShapes, nIndex);
879 nIndex -= nCount;
880 if (xAccessible.is())
881 break;
882 }
883
884 if (nIndex >= 0)
885 throw lang::IndexOutOfBoundsException();
886
887 return xAccessible;
888}
889
891{
892 sal_Int32 nCount(0);
893 for (auto const& shape : maShapeRanges)
894 nCount += shape.maControls.size();
895 return nCount;
896}
897
898uno::Reference<XAccessible> ScShapeChildren::GetControl(sal_Int32 nIndex) const
899{
900 uno::Reference<XAccessible> xAccessible;
901 for (const auto& rShapeRange : maShapeRanges)
902 {
903 sal_Int32 nCount(rShapeRange.maControls.size());
904 if(nIndex < nCount)
905 xAccessible = GetAccShape(rShapeRange.maControls, nIndex);
906 nIndex -= nCount;
907 if (xAccessible.is())
908 break;
909 }
910
911 if (nIndex >= 0)
912 throw lang::IndexOutOfBoundsException();
913
914 return xAccessible;
915}
916
917namespace {
918
919struct ScShapePointFound
920{
922 explicit ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {}
923 bool operator() (const ScShapeChild& rShape)
924 {
925 bool bResult(false);
926 if (VCLRectangle(rShape.mpAccShape->getBounds()).Contains(maPoint))
927 bResult = true;
928 return bResult;
929 }
930};
931
932}
933
934uno::Reference<XAccessible> ScShapeChildren::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls
935{
936 uno::Reference<XAccessible> xAcc;
937
938 for(const auto& rShapeRange : maShapeRanges)
939 {
940 ScShapeChildVec::const_iterator aFindItr = std::find_if(rShapeRange.maForeShapes.begin(), rShapeRange.maForeShapes.end(), ScShapePointFound(rPoint));
941 if (aFindItr != rShapeRange.maForeShapes.end())
942 xAcc = GetAccShape(*aFindItr);
943 else
944 {
945 ScShapeChildVec::const_iterator aCtrlItr = std::find_if(rShapeRange.maControls.begin(), rShapeRange.maControls.end(), ScShapePointFound(rPoint));
946 if (aCtrlItr != rShapeRange.maControls.end())
947 xAcc = GetAccShape(*aCtrlItr);
948 }
949
950 if (xAcc.is())
951 break;
952 }
953
954 return xAcc;
955}
956
957uno::Reference<XAccessible> ScShapeChildren::GetBackgroundShapeAt(const awt::Point& rPoint) const
958{
959 uno::Reference<XAccessible> xAcc;
960
961 for(const auto& rShapeRange : maShapeRanges)
962 {
963 ScShapeChildVec::const_iterator aFindItr = std::find_if(rShapeRange.maBackShapes.begin(), rShapeRange.maBackShapes.end(), ScShapePointFound(rPoint));
964 if (aFindItr != rShapeRange.maBackShapes.end())
965 xAcc = GetAccShape(*aFindItr);
966 if (xAcc.is())
967 break;
968 }
969
970 return xAcc;
971}
972
974{
975 if (!rShape.mpAccShape.is())
976 {
978 ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc);
979
980 if (mpViewShell)
981 {
983 aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView());
984 aShapeTreeInfo.SetController(nullptr);
985 aShapeTreeInfo.SetWindow(mpViewShell->GetWindow());
986 aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder));
987 rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo);
988 if (rShape.mpAccShape.is())
989 {
990 rShape.mpAccShape->Init();
991 }
992 }
993 }
994 return rShape.mpAccShape.get();
995}
996
998{
999 return GetAccShape(rShapes[nIndex]);
1000}
1001
1002void ScShapeChildren::FillShapes(const tools::Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId)
1003{
1004 OSL_ENSURE(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects");
1005 SdrPage* pPage = GetDrawPage();
1007 if (!(pPage && pWin))
1008 return;
1009
1010 bool bForeAdded(false);
1011 bool bBackAdded(false);
1012 bool bControlAdded(false);
1013 tools::Rectangle aClippedPixelPaintRect(aPixelPaintRect);
1014 if (mpAccDoc)
1015 {
1017 aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2);
1018 }
1019 ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode);
1020 maShapeRanges[nRangeId].maViewForwarder = aViewForwarder;
1021 const size_t nCount(pPage->GetObjCount());
1022 for (size_t i = 0; i < nCount; ++i)
1023 {
1024 SdrObject* pObj = pPage->GetObj(i);
1025 if (pObj)
1026 {
1027 uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1028 if (xShape.is())
1029 {
1030 tools::Rectangle aRect(pWin->LogicToPixel(
1031 tools::Rectangle(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize())), aMapMode));
1032 if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty())
1033 {
1034 ScShapeChild aShape;
1035 aShape.mxShape = xShape;
1036 aShape.mnRangeId = nRangeId;
1038 {
1039 maShapeRanges[nRangeId].maForeShapes.push_back(std::move(aShape));
1040 bForeAdded = true;
1041 }
1042 else if (pObj->GetLayer() == SC_LAYER_BACK)
1043 {
1044 maShapeRanges[nRangeId].maBackShapes.push_back(std::move(aShape));
1045 bBackAdded = true;
1046 }
1047 else if (pObj->GetLayer() == SC_LAYER_CONTROLS)
1048 {
1049 maShapeRanges[nRangeId].maControls.push_back(std::move(aShape));
1050 bControlAdded = true;
1051 }
1052 else
1053 {
1054 OSL_FAIL("I don't know this layer.");
1055 }
1056 }
1057 }
1058 }
1059 }
1060 if (bForeAdded)
1061 std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess());
1062 if (bBackAdded)
1063 std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess());
1064 if (bControlAdded)
1065 std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess());
1066}
1067
1069{
1071 SdrPage* pDrawPage = nullptr;
1073 if (rDoc.GetDrawLayer())
1074 {
1075 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1076 if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
1077 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
1078 }
1079 return pDrawPage;
1080}
1081
1082namespace {
1083
1084struct ScPagePreviewCountData
1085{
1086 // order is background shapes, header, table or notes, footer, foreground shapes, controls
1087
1088 tools::Rectangle aVisRect;
1089 tools::Long nBackShapes;
1090 tools::Long nHeaders;
1091 tools::Long nTables;
1092 tools::Long nNoteParagraphs;
1093 tools::Long nFooters;
1094 tools::Long nForeShapes;
1095 tools::Long nControls;
1096
1097 ScPagePreviewCountData( const ScPreviewLocationData& rData, const vcl::Window* pSizeWindow,
1098 const ScNotesChildren* pNotesChildren, const ScShapeChildren* pShapeChildren );
1099
1100 tools::Long GetTotal() const
1101 {
1102 return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls;
1103 }
1104};
1105
1106}
1107
1108ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData,
1109 const vcl::Window* pSizeWindow, const ScNotesChildren* pNotesChildren,
1110 const ScShapeChildren* pShapeChildren) :
1111 nBackShapes( 0 ),
1112 nHeaders( 0 ),
1113 nTables( 0 ),
1114 nNoteParagraphs( 0 ),
1115 nFooters( 0 ),
1116 nForeShapes( 0 ),
1117 nControls( 0 )
1118{
1119 Size aOutputSize;
1120 if ( pSizeWindow )
1121 aOutputSize = pSizeWindow->GetOutputSizePixel();
1122 aVisRect = tools::Rectangle( Point(), aOutputSize );
1123
1124 tools::Rectangle aObjRect;
1125
1126 if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.Overlaps( aVisRect ) )
1127 nHeaders = 1;
1128
1129 if ( rData.GetFooterPosition( aObjRect ) && aObjRect.Overlaps( aVisRect ) )
1130 nFooters = 1;
1131
1132 if ( rData.HasCellsInRange( aVisRect ) )
1133 nTables = 1;
1134
1136 nBackShapes = pShapeChildren->GetBackShapeCount();
1137 nForeShapes = pShapeChildren->GetForeShapeCount();
1138 nControls = pShapeChildren->GetControlCount();
1139
1140 // there are only notes if there is no table
1141 if (nTables == 0)
1142 nNoteParagraphs = pNotesChildren->GetChildrenCount();
1143}
1144
1145//===== internal ========================================================
1146
1148 const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) :
1149 ScAccessibleDocumentBase(rxParent),
1150 mpViewShell(pViewShell)
1151{
1152 if (pViewShell)
1153 pViewShell->AddAccessibilityObject(*this);
1154
1155}
1156
1158{
1159 if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose)
1160 {
1161 // increment refcount to prevent double call off dtor
1162 osl_atomic_increment( &m_refCount );
1163 // call dispose to inform object which have a weak reference to this object
1164 dispose();
1165 }
1166}
1167
1169{
1170 SolarMutexGuard aGuard;
1171 mpTable.clear();
1172 mpHeader.clear();
1173 mpFooter.clear();
1174
1175 if (mpViewShell)
1176 {
1178 mpViewShell = nullptr;
1179 }
1180
1181 // no need to Dispose the AccessibleTextHelper,
1182 // as long as mpNotesChildren are destructed here
1183 mpNotesChildren.reset();
1184
1185 mpShapeChildren.reset();
1186
1188}
1189
1190//===== SfxListener =====================================================
1191
1193{
1194 if ( dynamic_cast<const ScAccWinFocusLostHint*>(&rHint) )
1195 {
1197 }
1198 else if ( dynamic_cast<const ScAccWinFocusGotHint*>(&rHint) )
1199 {
1201 }
1202 else
1203 {
1204 // only notify if child exist, otherwise it is not necessary
1205 if (rHint.GetId() == SfxHintId::ScDataChanged)
1206 {
1207 if (mpTable.is()) // if there is no table there is nothing to notify, because no one recognizes the change
1208 {
1209 {
1210 uno::Reference<XAccessible> xAcc = mpTable;
1211 AccessibleEventObject aEvent;
1212 aEvent.EventId = AccessibleEventId::CHILD;
1213 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1214 aEvent.OldValue <<= xAcc;
1215 aEvent.IndexHint = -1;
1217 }
1218
1219 mpTable->dispose();
1220 mpTable.clear();
1221 }
1222
1223 Size aOutputSize;
1224 vcl::Window* pSizeWindow = mpViewShell->GetWindow();
1225 if ( pSizeWindow )
1226 aOutputSize = pSizeWindow->GetOutputSizePixel();
1227 tools::Rectangle aVisRect( Point(), aOutputSize );
1228 GetNotesChildren()->DataChanged(aVisRect);
1229
1231
1233 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1234
1235 if (aCount.nTables > 0)
1236 {
1238 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1239
1241 mpTable->Init();
1242
1243 {
1244 uno::Reference<XAccessible> xAcc = mpTable;
1245 AccessibleEventObject aEvent;
1246 aEvent.EventId = AccessibleEventId::CHILD;
1247 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1248 aEvent.NewValue <<= xAcc;
1249 aEvent.IndexHint = -1;
1251 }
1252 }
1253 }
1254 else if (rHint.GetId() == SfxHintId::ScAccVisAreaChanged)
1255 {
1256 Size aOutputSize;
1257 vcl::Window* pSizeWindow = mpViewShell->GetWindow();
1258 if ( pSizeWindow )
1259 aOutputSize = pSizeWindow->GetOutputSizePixel();
1260 tools::Rectangle aVisRect( Point(), aOutputSize );
1261 GetNotesChildren()->DataChanged(aVisRect);
1262
1264
1265 AccessibleEventObject aEvent;
1266 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
1267 aEvent.Source = uno::Reference< XAccessibleContext >(this);
1269 }
1270 }
1272}
1273
1274//===== XAccessibleComponent ============================================
1275
1276uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint )
1277{
1278 uno::Reference<XAccessible> xAccessible;
1279 if (containsPoint(rPoint))
1280 {
1281 SolarMutexGuard aGuard;
1282 IsObjectValid();
1283
1284 if ( mpViewShell )
1285 {
1286 xAccessible = GetShapeChildren()->GetForegroundShapeAt(rPoint);
1287 if (!xAccessible.is())
1288 {
1290 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1291
1292 if ( !mpTable.is() && (aCount.nTables > 0) )
1293 {
1295 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1296
1298 mpTable->Init();
1299 }
1300 if (mpTable.is() && VCLRectangle(mpTable->getBounds()).Contains(VCLPoint(rPoint)))
1301 xAccessible = mpTable.get();
1302 }
1303 if (!xAccessible.is())
1304 xAccessible = GetNotesChildren()->GetAt(rPoint);
1305 if (!xAccessible.is())
1306 {
1307 if (!mpHeader.is() || !mpFooter.is())
1308 {
1310 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1311
1312 if (!mpHeader.is())
1313 {
1314 mpHeader = new ScAccessiblePageHeader( this, mpViewShell, true, aCount.nBackShapes + aCount.nHeaders - 1);
1315 }
1316 if (!mpFooter.is())
1317 {
1318 mpFooter = new ScAccessiblePageHeader( this, mpViewShell, false, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 );
1319 }
1320 }
1321
1322 Point aPoint(VCLPoint(rPoint));
1323
1324 if (VCLRectangle(mpHeader->getBounds()).Contains(aPoint))
1325 xAccessible = mpHeader.get();
1326 else if (VCLRectangle(mpFooter->getBounds()).Contains(aPoint))
1327 xAccessible = mpFooter.get();
1328 }
1329 if (!xAccessible.is())
1330 xAccessible = GetShapeChildren()->GetBackgroundShapeAt(rPoint);
1331 }
1332 }
1333
1334 return xAccessible;
1335}
1336
1338{
1339 SolarMutexGuard aGuard;
1340 IsObjectValid();
1341 if (getAccessibleParent().is())
1342 {
1343 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1344 if (xAccessibleComponent.is())
1345 {
1346 // just grab the focus for the window
1347 xAccessibleComponent->grabFocus();
1348 }
1349 }
1350}
1351
1352//===== XAccessibleContext ==============================================
1353
1355{
1356 SolarMutexGuard aGuard;
1357 IsObjectValid();
1358
1359 sal_Int64 nRet = 0;
1360 if ( mpViewShell )
1361 {
1362 ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1363 nRet = aCount.GetTotal();
1364 }
1365
1366 return nRet;
1367}
1368
1369uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int64 nIndex)
1370{
1371 SolarMutexGuard aGuard;
1372 IsObjectValid();
1373 uno::Reference<XAccessible> xAccessible;
1374
1375 if ( mpViewShell )
1376 {
1378 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1379
1380 if ( nIndex < aCount.nBackShapes )
1381 {
1382 xAccessible = GetShapeChildren()->GetBackShape(nIndex);
1383 }
1384 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders )
1385 {
1386 if ( !mpHeader.is() )
1387 {
1388 mpHeader = new ScAccessiblePageHeader( this, mpViewShell, true, nIndex );
1389 }
1390
1391 xAccessible = mpHeader.get();
1392 }
1393 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables )
1394 {
1395 if ( !mpTable.is() )
1396 {
1398 mpTable->Init();
1399 }
1400 xAccessible = mpTable.get();
1401 }
1402 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs )
1403 {
1404 xAccessible = GetNotesChildren()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders);
1405 }
1406 else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters )
1407 {
1408 if ( !mpFooter.is() )
1409 {
1410 mpFooter = new ScAccessiblePageHeader( this, mpViewShell, false, nIndex );
1411 }
1412 xAccessible = mpFooter.get();
1413 }
1414 else
1415 {
1416 sal_Int64 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters));
1417 if (nIdx < aCount.nForeShapes)
1418 xAccessible = GetShapeChildren()->GetForeShape(nIdx);
1419 else
1420 xAccessible = GetShapeChildren()->GetControl(nIdx - aCount.nForeShapes);
1421 }
1422 }
1423
1424 if ( !xAccessible.is() )
1425 throw lang::IndexOutOfBoundsException();
1426
1427 return xAccessible;
1428}
1429
1432{
1433 SolarMutexGuard aGuard;
1434 sal_Int64 nParentStates = 0;
1435 if (getAccessibleParent().is())
1436 {
1437 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1438 nParentStates = xParentContext->getAccessibleStateSet();
1439 }
1440 sal_Int64 nStateSet = 0;
1441 if (IsDefunc(nParentStates))
1442 nStateSet |= AccessibleStateType::DEFUNC;
1443 else
1444 {
1445 // never editable
1446 nStateSet |= AccessibleStateType::ENABLED;
1447 nStateSet |= AccessibleStateType::OPAQUE;
1448 if (isShowing())
1449 nStateSet |= AccessibleStateType::SHOWING;
1450 if (isVisible())
1451 nStateSet |= AccessibleStateType::VISIBLE;
1452 }
1453 return nStateSet;
1454}
1455
1456 //===== XServiceInfo ====================================================
1457
1459{
1460 return "ScAccessibleDocumentPagePreview";
1461}
1462
1464{
1465 const css::uno::Sequence<OUString> vals { "com.sun.star.AccessibleSpreadsheetPageView" };
1467}
1468
1469//===== XTypeProvider =======================================================
1470
1471uno::Sequence<sal_Int8> SAL_CALL
1473{
1474 return css::uno::Sequence<sal_Int8>();
1475}
1476
1477//===== internal ========================================================
1478
1480{
1482}
1483
1485{
1486 OUString sName = ScResId(STR_ACC_PREVIEWDOC_NAME);
1487 return sName;
1488}
1489
1491{
1492 tools::Rectangle aRect;
1493 if (mpViewShell)
1494 {
1495 vcl::Window* pWindow = mpViewShell->GetWindow();
1496 if (pWindow)
1497 aRect = pWindow->GetWindowExtentsAbsolute();
1498 }
1499 return aRect;
1500}
1501
1503{
1504 tools::Rectangle aRect;
1505 if (mpViewShell)
1506 {
1507 vcl::Window* pWindow = mpViewShell->GetWindow();
1508 if (pWindow)
1509 aRect = pWindow->GetWindowExtentsRelative(*pWindow->GetAccessibleParentWindow());
1510 }
1511 return aRect;
1512}
1513
1515{
1517 (nParentStates & AccessibleStateType::DEFUNC);
1518}
1519
1521{
1523 {
1524 mpNotesChildren.reset( new ScNotesChildren(mpViewShell, this) );
1525
1527 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChildren(), GetShapeChildren() );
1528
1530 mpNotesChildren->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders);
1531 }
1532 return mpNotesChildren.get();
1533}
1534
1536{
1538 {
1539 mpShapeChildren.reset( new ScShapeChildren(mpViewShell, this) );
1540 mpShapeChildren->Init();
1541 }
1542
1543 return mpShapeChildren.get();
1544}
1545
1547{
1549
1550 OUString aName = ScResId(STR_ACC_DOC_SPREADSHEET);
1551 ScDocument& rScDoc = mpViewShell->GetDocument();
1552
1553 SfxObjectShell* pObjSh = rScDoc.GetDocumentShell();
1554 if (!pObjSh)
1555 return aName;
1556
1557 OUString aFileName;
1558 SfxMedium* pMed = pObjSh->GetMedium();
1559 if (pMed)
1560 aFileName = pMed->GetName();
1561
1562 if (aFileName.isEmpty())
1563 aFileName = pObjSh->GetTitle(SFX_TITLE_APINAME);
1564
1565 if (!aFileName.isEmpty())
1566 {
1567 aName = aFileName + " - " + aName + ScResId(STR_ACC_DOC_PREVIEW_SUFFIX);
1568
1569 }
1570
1571 return aName;
1572}
1573
1574/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< ScShapeRange > ScShapeRangeVec
std::vector< uno::Reference< XAccessible > > ScXAccVector
std::vector< ScShapeChild > ScShapeChildVec
AnyEventRef aEvent
B2DPoint maPoint
virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point &rPoint) override
===== XAccessibleComponent ============================================
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override
===== XAccessible =====================================================
virtual void SAL_CALL disposing() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Returns a list of all supported services.
void CommitFocusLost() const
Calls all FocusListener to tell they that the focus is lost.
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
===== SfxListener =====================================================
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
Return a reference to the parent.
void CommitFocusGained() const
Calls all FocusListener to tell they that the focus is gained.
void CommitChange(const css::accessibility::AccessibleEventObject &rEvent) const
Calls all Listener to tell they the change.
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Returns a list of all supported services.
rtl::Reference< ScAccessiblePreviewTable > mpTable
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
===== XTypeProvider ===================================================
virtual OUString SAL_CALL getAccessibleName() override
Return the object's current name.
virtual OUString createAccessibleName() override
Return the object's current name.
rtl::Reference< ScAccessiblePageHeader > mpFooter
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint(const css::awt::Point &rPoint) override
===== XAccessibleComponent ============================================
virtual void SAL_CALL disposing() override
virtual tools::Rectangle GetBoundingBox() const override
Return the object's current bounding box relative to the parent object.
virtual sal_Int64 SAL_CALL getAccessibleChildCount() override
===== XAccessibleContext ==============================================
virtual OUString createAccessibleDescription() override
===== internal ========================================================
std::unique_ptr< ScNotesChildren > mpNotesChildren
virtual void SAL_CALL grabFocus() override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int64 nIndex) override
Return the specified child or NULL if index is invalid.
rtl::Reference< ScAccessiblePageHeader > mpHeader
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
===== SfxListener =====================================================
virtual sal_Int64 SAL_CALL getAccessibleStateSet() override
Return the set of current states.
virtual tools::Rectangle GetBoundingBoxOnScreen() const override
Return the object's current bounding box relative to the desktop.
virtual OUString SAL_CALL getImplementationName() override
===== XServiceInfo ====================================================
ScAccessibleDocumentPagePreview(const css::uno::Reference< css::accessibility::XAccessible > &rxParent, ScPreviewShell *pViewShell)
std::unique_ptr< ScShapeChildren > mpShapeChildren
SCTAB Tab() const
Definition: address.hxx:283
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
Definition: document.cxx:6587
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1084
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
bool HasObjects() const
Definition: drwlayer.cxx:430
sal_Int32 GetChildrenCount() const
void Init(const tools::Rectangle &rVisRect, sal_Int32 nOffset)
sal_Int32 CheckChanges(const ScPreviewLocationData &rData, const tools::Rectangle &rVisRect, bool bMark, ScAccNotes &rOldNotes, ScAccNotes &rNewNotes, ScXAccVector &rOldParas, ScXAccVector &rNewParas)
uno::Reference< XAccessible > GetChild(sal_Int32 nIndex) const
::accessibility::AccessibleTextHelper * CreateTextHelper(const OUString &rString, const tools::Rectangle &rVisRect, const ScAddress &aCellPos, bool bMarkNote, sal_Int32 nChildOffset) const
uno::Reference< XAccessible > GetAt(const awt::Point &rPoint) const
std::vector< ScAccNote > ScAccNotes
static void CollectChildren(const ScAccNote &rNote, ScXAccVector &rVector)
sal_Int32 AddNotes(const ScPreviewLocationData &rData, const tools::Rectangle &rVisRect, bool bMark, ScAccNotes &rNotes)
ScNotesChildren(ScPreviewShell *pViewShell, ScAccessibleDocumentPagePreview *pAccDoc)
void DataChanged(const tools::Rectangle &rVisRect)
static sal_Int8 CompareCell(const ScAddress &aCell1, const ScAddress &aCell2)
ScDocument * GetDocument() const
ScAccessibleDocumentPagePreview * mpAccDoc
Additional class containing cell annotation data.
Definition: postit.hxx:58
bool GetHeaderPosition(tools::Rectangle &rHeaderRect) const
Definition: prevloc.cxx:334
bool GetNoteInRange(const tools::Rectangle &rVisiblePixel, tools::Long nIndex, bool bNoteMarks, ScAddress &rCellPos, tools::Rectangle &rNoteRect) const
Definition: prevloc.cxx:404
sal_uInt16 GetDrawRanges() const
Definition: prevloc.hxx:122
bool HasCellsInRange(const tools::Rectangle &rVisiblePixel) const
Definition: prevloc.cxx:322
tools::Long GetNoteCountInRange(const tools::Rectangle &rVisiblePixel, bool bNoteMarks) const
Definition: prevloc.cxx:390
bool GetFooterPosition(tools::Rectangle &rFooterRect) const
Definition: prevloc.cxx:348
SCTAB GetPrintTab() const
Definition: prevloc.hxx:117
void GetDrawRange(sal_uInt16 nPos, tools::Rectangle &rPixelRect, MapMode &rMapMode, sal_uInt8 &rRangeId) const
Definition: prevloc.cxx:256
const ScPreviewLocationData & GetLocationData()
Definition: prevwsh.cxx:1171
void AddAccessibilityObject(SfxListener &rObject)
Definition: prevwsh.cxx:1142
ScDocument & GetDocument()
Definition: prevwsh.cxx:1176
ScPreview * GetPreview()
Definition: prevwsh.hxx:118
void RemoveAccessibilityObject(SfxListener &rObject)
Definition: prevwsh.cxx:1150
FmFormView * GetDrawView()
Definition: preview.hxx:157
void FillShapes(const tools::Rectangle &aPixelPaintRect, const MapMode &aMapMode, sal_uInt8 nRangeId)
void Init()
===== Internal ========================================================
uno::Reference< XAccessible > GetControl(sal_Int32 nIndex) const
ScAccessibleDocumentPagePreview * mpAccDoc
uno::Reference< XAccessible > GetForegroundShapeAt(const awt::Point &rPoint) const
uno::Reference< XAccessible > GetBackShape(sal_Int32 nIndex) const
uno::Reference< XAccessible > GetForeShape(sal_Int32 nIndex) const
ScShapeChildren(ScPreviewShell *pViewShell, ScAccessibleDocumentPagePreview *pAccDoc)
void FindChanged(ScShapeChildVec &aOld, ScShapeChildVec &aNew) const
uno::Reference< XAccessible > GetBackgroundShapeAt(const awt::Point &rPoint) const
virtual bool ReplaceChild(::accessibility::AccessibleShape *pCurrentChild, const css::uno::Reference< css::drawing::XShape > &_rxShape, const tools::Long _nIndex, const ::accessibility::AccessibleShapeTreeInfo &_rShapeTreeInfo) override
===== IAccessibleParent ==============================================
::accessibility::AccessibleShape * GetAccShape(const ScShapeChild &rShape) const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
sal_uInt16 GetPageCount() const
SdrObject * GetObj(size_t nNum) const
size_t GetObjCount() const
virtual css::uno::Reference< css::drawing::XShape > getUnoShape()
virtual SdrLayerID GetLayer() const
SfxHintId GetId() const
const OUString & GetName() const
SfxMedium * GetMedium() const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
vcl::Window * GetWindow() const
void SetViewForwarder(const IAccessibleViewForwarder *pViewForwarder)
void SetWindow(vcl::Window *pWindow)
void SetController(const css::uno::Reference< css::frame::XController > &rxController)
void SetStartIndex(sal_Int32 nOffset)
void SetEventSource(const css::uno::Reference< css::accessibility::XAccessible > &rInterface)
void SetOffset(const Point &rPoint)
virtual Point LogicToPixel(const Point &rPoint) const=0
virtual tools::Rectangle GetVisibleArea() const=0
rtl::Reference< AccessibleShape > CreateAccessibleObject(const AccessibleShapeInfo &rShapeInfo, const AccessibleShapeTreeInfo &rShapeTreeInfo) const
static ShapeTypeHandler & Instance()
bool Contains(const Point &rPOINT) const
bool Overlaps(const tools::Rectangle &rRect) const
tools::Rectangle GetIntersection(const tools::Rectangle &rRect) const
void SetSize(const Size &)
constexpr Point TopLeft() const
void SetPos(const Point &rPoint)
constexpr Size GetSize() const
constexpr bool IsEmpty() const
tools::Rectangle GetWindowExtentsAbsolute() const
Point LogicToPixel(const Point &rLogicPt) const
vcl::Window * GetWindow(GetWindowType nType) const
vcl::Window * GetAccessibleParentWindow() const
Point PixelToLogic(const Point &rDevicePt) const
Size GetOutputSizePixel() const
tools::Rectangle GetWindowExtentsRelative(const vcl::Window &rRelativeWindow) const
inline ::tools::Rectangle VCLRectangle(const css::awt::Rectangle &rAWTRect)
inline ::Size VCLSize(const css::awt::Size &rAWTSize)
inline ::Point VCLPoint(const css::awt::Point &rAWTPoint)
int nCount
ULONG m_refCount
OUString sName
constexpr SdrLayerID SC_LAYER_FRONT(0)
constexpr SdrLayerID SC_LAYER_INTERN(2)
constexpr SdrLayerID SC_LAYER_BACK(1)
constexpr SdrLayerID SC_LAYER_CONTROLS(3)
sal_Int32 nIndex
OUString aName
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
int i
void dispose()
long Long
#define SFX_TITLE_APINAME
#define SC_PREVIEW_MAXRANGES
Definition: prevloc.hxx:33
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
uno::Reference< drawing::XShape > const mxShape
constexpr OUStringLiteral STR_ACC_PREVIEWDOC_DESCR
Definition: strings.hxx:19
bool anyOf(strong_int v) const
sal_uInt32 mnIndex
sal_Int32 mnParaCount
unsigned char sal_uInt8
signed char sal_Int8
sal_Int16 SCTAB
Definition: types.hxx:22