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