1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleDocumentPagePreview.cxx,v $
10 * $Revision: 1.38.128.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "AccessibleDocumentPagePreview.hxx"
35 #include "AccessiblePreviewTable.hxx"
36 #include "AccessiblePageHeader.hxx"
37 #include "AccessibilityHints.hxx"
38 #include "AccessibleText.hxx"
39 #include "document.hxx"
40 #include "prevwsh.hxx"
41 #include "prevloc.hxx"
42 #include "unoguard.hxx"
43 #include "drwlayer.hxx"
44 #include "editsrc.hxx"
45 #include "scresid.hxx"
47 #include "DrawModelBroadcaster.hxx"
49 #include "drawview.hxx"
50 #include "preview.hxx"
53 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
54 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
55 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
57 #include <unotools/accessiblestatesethelper.hxx>
58 #include <tools/debug.hxx>
59 #include <tools/gen.hxx>
60 #include <svx/svdpage.hxx>
61 #include <svx/svdobj.hxx>
62 #include <svx/AccessibleTextHelper.hxx>
63 #include <svx/AccessibleShape.hxx>
64 #include <svx/ShapeTypeHandler.hxx>
65 #include <toolkit/helper/convert.hxx>
66 #include <svx/unoshape.hxx>
67 #include <unotools/accessiblerelationsethelper.hxx>
74 using namespace ::com::sun::star
;
75 using namespace ::com::sun::star::accessibility
;
77 //=========================================================================
79 typedef std::list
< uno::Reference
< XAccessible
> > ScXAccList
;
87 ::accessibility::AccessibleTextHelper
* mpTextHelper
;
88 sal_Int32 mnParaCount
;
91 ScAccNote() : mpTextHelper(NULL
), mnParaCount(0) {}
97 ScNotesChilds(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
);
99 void Init(const Rectangle
& rVisRect
, sal_Int32 nOffset
);
101 sal_Int32
GetChildsCount() const;
102 uno::Reference
<XAccessible
> GetChild(sal_Int32 nIndex
) const;
103 uno::Reference
<XAccessible
> GetAt(const awt::Point
& rPoint
) const;
105 void DataChanged(const Rectangle
& rVisRect
);
106 void SetOffset(sal_Int32 nNewOffset
);
108 ScPreviewShell
* mpViewShell
;
109 ScAccessibleDocumentPagePreview
* mpAccDoc
;
110 typedef std::vector
<ScAccNote
> ScAccNotes
;
111 mutable ScAccNotes maNotes
;
112 mutable ScAccNotes maMarks
;
113 sal_Int32 mnParagraphs
;
116 ::accessibility::AccessibleTextHelper
* CreateTextHelper(const String
& rString
, const Rectangle
& rVisRect
, const ScAddress
& aCellPos
, sal_Bool bMarkNote
, sal_Int32 nChildOffset
) const;
117 sal_Int32
AddNotes(const ScPreviewLocationData
& rData
, const Rectangle
& rVisRect
, sal_Bool bMark
, ScAccNotes
& rNotes
);
119 sal_Int8
CompareCell(const ScAddress
& aCell1
, const ScAddress
& aCell2
);
120 void CollectChilds(const ScAccNote
& rNote
, ScXAccList
& rList
);
121 sal_Int32
CheckChanges(const ScPreviewLocationData
& rData
, const Rectangle
& rVisRect
,
122 sal_Bool bMark
, ScAccNotes
& rOldNotes
, ScAccNotes
& rNewNotes
,
123 ScXAccList
& rOldParas
, ScXAccList
& rNewParas
);
125 inline ScDocument
* GetDocument() const;
128 ScNotesChilds::ScNotesChilds(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
)
129 : mpViewShell(pViewShell
),
138 void operator()(ScAccNote
& rNote
)
140 if (rNote
.mpTextHelper
)
141 DELETEZ( rNote
.mpTextHelper
);
145 ScNotesChilds::~ScNotesChilds()
147 std::for_each(maNotes
.begin(), maNotes
.end(), DeleteAccNote());
148 std::for_each(maMarks
.begin(), maMarks
.end(), DeleteAccNote());
151 ::accessibility::AccessibleTextHelper
* ScNotesChilds::CreateTextHelper(const String
& rString
, const Rectangle
& rVisRect
, const ScAddress
& aCellPos
, sal_Bool bMarkNote
, sal_Int32 nChildOffset
) const
153 ::accessibility::AccessibleTextHelper
* pTextHelper
= NULL
;
155 ::std::auto_ptr
< ScAccessibleTextData
> pAccessiblePreviewHeaderCellTextData
156 (new ScAccessibleNoteTextData(mpViewShell
, rString
, aCellPos
, bMarkNote
));
157 ::std::auto_ptr
< SvxEditSource
> pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData
));
159 pTextHelper
= new ::accessibility::AccessibleTextHelper(pEditSource
);
163 pTextHelper
->SetEventSource(mpAccDoc
);
164 pTextHelper
->SetStartIndex(nChildOffset
);
165 pTextHelper
->SetOffset(rVisRect
.TopLeft());
171 sal_Int32
ScNotesChilds::AddNotes(const ScPreviewLocationData
& rData
, const Rectangle
& rVisRect
, sal_Bool bMark
, ScAccNotes
& rNotes
)
173 sal_Int32 nCount
= rData
.GetNoteCountInRange(rVisRect
, bMark
);
175 rNotes
.reserve(nCount
);
177 sal_Int32
nParagraphs(0);
178 ScDocument
* pDoc
= GetDocument();
182 aNote
.mbMarkNote
= bMark
;
184 aNote
.mnParaCount
= 1;
185 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
187 if (rData
.GetNoteInRange(rVisRect
, nIndex
, bMark
, aNote
.maNoteCell
, aNote
.maRect
))
191 // Document not needed, because only the cell address, but not the tablename is needed
192 aNote
.maNoteCell
.Format( aNote
.maNoteText
, SCA_VALID
, NULL
);
196 if( ScPostIt
* pNote
= pDoc
->GetNote( aNote
.maNoteCell
) )
197 aNote
.maNoteText
= pNote
->GetText();
198 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
199 if (aNote
.mpTextHelper
)
200 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
202 nParagraphs
+= aNote
.mnParaCount
;
203 rNotes
.push_back(aNote
);
210 void ScNotesChilds::Init(const Rectangle
& rVisRect
, sal_Int32 nOffset
)
212 if (mpViewShell
&& !mnParagraphs
)
215 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
217 mnParagraphs
= AddNotes(rData
, rVisRect
, sal_False
, maMarks
);
218 mnParagraphs
+= AddNotes(rData
, rVisRect
, sal_True
, maNotes
);
222 sal_Int32
ScNotesChilds::GetChildsCount() const
230 ScParaFound(sal_Int32 nIndex
) : mnIndex(nIndex
) {}
231 sal_Bool
operator() (const ScAccNote
& rNote
)
233 sal_Bool
bResult(sal_False
);
234 if (rNote
.mnParaCount
> mnIndex
)
237 mnIndex
-= rNote
.mnParaCount
;
242 uno::Reference
<XAccessible
> ScNotesChilds::GetChild(sal_Int32 nIndex
) const
244 uno::Reference
<XAccessible
> xAccessible
;
246 if (nIndex
< mnParagraphs
)
248 if (nIndex
< static_cast<sal_Int32
>(maMarks
.size()))
250 ScAccNotes::iterator aEndItr
= maMarks
.end();
251 ScParaFound
aParaFound(nIndex
);
252 ScAccNotes::iterator aItr
= std::find_if(maMarks
.begin(), aEndItr
, aParaFound
);
255 DBG_ASSERT((aItr
->maNoteCell
== maMarks
[nIndex
].maNoteCell
) && (aItr
->mbMarkNote
== maMarks
[nIndex
].mbMarkNote
), "wrong note found");
259 DBG_ERRORFILE("wrong note found");
261 if (!aItr
->mpTextHelper
)
262 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
263 xAccessible
= aItr
->mpTextHelper
->GetChild(aParaFound
.mnIndex
+ aItr
->mpTextHelper
->GetStartIndex());
267 nIndex
-= maMarks
.size();
268 ScAccNotes::iterator aEndItr
= maNotes
.end();
269 ScParaFound
aParaFound(nIndex
);
270 ScAccNotes::iterator aItr
= std::find_if(maNotes
.begin(), aEndItr
, aParaFound
);
273 if (!aItr
->mpTextHelper
)
274 aItr
->mpTextHelper
= CreateTextHelper(aItr
->maNoteText
, aItr
->maRect
, aItr
->maNoteCell
, aItr
->mbMarkNote
, (nIndex
- aParaFound
.mnIndex
) + mnOffset
+ maMarks
.size());
275 xAccessible
= aItr
->mpTextHelper
->GetChild(aParaFound
.mnIndex
+ aItr
->mpTextHelper
->GetStartIndex());
286 sal_Int32 mnParagraphs
;
287 ScPointFound(const Point
& rPoint
) : maPoint(rPoint
, Size(0, 0)), mnParagraphs(0) {}
288 sal_Bool
operator() (const ScAccNote
& rNote
)
290 sal_Bool
bResult(sal_False
);
291 if (maPoint
.IsInside(rNote
.maRect
))
294 mnParagraphs
+= rNote
.mnParaCount
;
299 uno::Reference
<XAccessible
> ScNotesChilds::GetAt(const awt::Point
& rPoint
) const
301 uno::Reference
<XAccessible
> xAccessible
;
303 ScPointFound
aPointFound(Point(rPoint
.X
, rPoint
.Y
));
305 ScAccNotes::iterator aEndItr
= maMarks
.end();
306 ScAccNotes::iterator aItr
= std::find_if(maMarks
.begin(), aEndItr
, aPointFound
);
309 aEndItr
= maNotes
.end();
310 aItr
= std::find_if(maNotes
.begin(), aEndItr
, aPointFound
);
314 if (!aItr
->mpTextHelper
)
315 aItr
->mpTextHelper
= CreateTextHelper(aItr
->maNoteText
, aItr
->maRect
, aItr
->maNoteCell
, aItr
->mbMarkNote
, aPointFound
.mnParagraphs
+ mnOffset
);
316 xAccessible
= aItr
->mpTextHelper
->GetAt(rPoint
);
322 sal_Int8
ScNotesChilds::CompareCell(const ScAddress
& aCell1
, const ScAddress
& aCell2
)
324 DBG_ASSERT(aCell1
.Tab() == aCell2
.Tab(), "the notes should be on the same table");
326 if (aCell1
!= aCell2
)
328 if (aCell1
.Row() == aCell2
.Row())
329 nResult
= (aCell1
.Col() < aCell2
.Col()) ? -1 : 1;
331 nResult
= (aCell1
.Row() < aCell2
.Row()) ? -1 : 1;
336 void ScNotesChilds::CollectChilds(const ScAccNote
& rNote
, ScXAccList
& rList
)
338 if (rNote
.mpTextHelper
)
339 for (sal_Int32 i
= 0; i
< rNote
.mnParaCount
; ++i
)
340 rList
.push_back(rNote
.mpTextHelper
->GetChild(i
+ rNote
.mpTextHelper
->GetStartIndex()));
343 sal_Int32
ScNotesChilds::CheckChanges(const ScPreviewLocationData
& rData
,
344 const Rectangle
& rVisRect
, sal_Bool bMark
, ScAccNotes
& rOldNotes
,
345 ScAccNotes
& rNewNotes
, ScXAccList
& rOldParas
, ScXAccList
& rNewParas
)
347 sal_Int32 nCount
= rData
.GetNoteCountInRange(rVisRect
, bMark
);
349 rNewNotes
.reserve(nCount
);
351 sal_Int32
nParagraphs(0);
352 ScDocument
* pDoc
= GetDocument();
356 aNote
.mbMarkNote
= bMark
;
358 aNote
.mnParaCount
= 1;
359 ScAccNotes::iterator aItr
= rOldNotes
.begin();
360 ScAccNotes::iterator aEndItr
= rOldNotes
.end();
361 sal_Bool
bAddNote(sal_False
);
362 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
364 if (rData
.GetNoteInRange(rVisRect
, nIndex
, bMark
, aNote
.maNoteCell
, aNote
.maRect
))
368 // Document not needed, because only the cell address, but not the tablename is needed
369 aNote
.maNoteCell
.Format( aNote
.maNoteText
, SCA_VALID
, NULL
);
373 if( ScPostIt
* pNote
= pDoc
->GetNote( aNote
.maNoteCell
) )
374 aNote
.maNoteText
= pNote
->GetText();
377 sal_Int8
nCompare(-1); // if there are no more old childs it is always a new one
379 nCompare
= CompareCell(aNote
.maNoteCell
, aItr
->maNoteCell
);
382 if (aNote
.maNoteText
== aItr
->maNoteText
)
384 aNote
.mpTextHelper
= aItr
->mpTextHelper
;
385 if (aNote
.maRect
!= aItr
->maRect
) //neue VisArea setzen
387 aNote
.mpTextHelper
->SetOffset(aNote
.maRect
.TopLeft());
388 aNote
.mpTextHelper
->UpdateChildren();
389 //DBG_ASSERT(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
390 // could be changed, because only a part of the note is visible
395 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
396 if (aNote
.mpTextHelper
)
397 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
398 // collect removed childs
399 CollectChilds(*aItr
, rOldParas
);
400 DELETEZ(aItr
->mpTextHelper
);
401 // collect new childs
402 CollectChilds(aNote
, rNewParas
);
405 // not necessary, because this branch should not be reached if it is the end
406 //if (aItr != aEndItr)
409 else if (nCompare
< 0)
411 aNote
.mpTextHelper
= CreateTextHelper(aNote
.maNoteText
, aNote
.maRect
, aNote
.maNoteCell
, aNote
.mbMarkNote
, nParagraphs
+ mnOffset
);
412 if (aNote
.mpTextHelper
)
413 aNote
.mnParaCount
= aNote
.mpTextHelper
->GetChildCount();
414 // collect new childs
415 CollectChilds(aNote
, rNewParas
);
420 // collect removed childs
421 CollectChilds(*aItr
, rOldParas
);
422 DELETEZ(aItr
->mpTextHelper
);
425 // not necessary, because this branch should not be reached if it is the end
426 //if (aItr != aEndItr)
431 nParagraphs
+= aNote
.mnParaCount
;
432 rNewNotes
.push_back(aNote
);
433 bAddNote
= sal_False
;
443 ScAccessibleDocumentPagePreview
* mpAccDoc
;
444 ScChildGone(ScAccessibleDocumentPagePreview
* pAccDoc
) : mpAccDoc(pAccDoc
) {}
445 void operator() (const uno::Reference
<XAccessible
>& xAccessible
) const
449 AccessibleEventObject aEvent
;
450 aEvent
.EventId
= AccessibleEventId::CHILD
;
451 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccDoc
);
452 aEvent
.OldValue
<<= xAccessible
;
454 mpAccDoc
->CommitChange(aEvent
); // gone child - event
461 ScAccessibleDocumentPagePreview
* mpAccDoc
;
462 ScChildNew(ScAccessibleDocumentPagePreview
* pAccDoc
) : mpAccDoc(pAccDoc
) {}
463 void operator() (const uno::Reference
<XAccessible
>& xAccessible
) const
467 AccessibleEventObject aEvent
;
468 aEvent
.EventId
= AccessibleEventId::CHILD
;
469 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(mpAccDoc
);
470 aEvent
.NewValue
<<= xAccessible
;
472 mpAccDoc
->CommitChange(aEvent
); // new child - event
477 void ScNotesChilds::DataChanged(const Rectangle
& rVisRect
)
479 if (mpViewShell
&& mpAccDoc
)
481 ScXAccList aNewParas
;
482 ScXAccList aOldParas
;
483 ScAccNotes aNewMarks
;
484 mnParagraphs
= CheckChanges(mpViewShell
->GetLocationData(), rVisRect
, sal_True
, maMarks
, aNewMarks
, aOldParas
, aNewParas
);
486 ScAccNotes aNewNotes
;
487 mnParagraphs
+= CheckChanges(mpViewShell
->GetLocationData(), rVisRect
, sal_False
, maNotes
, aNewNotes
, aOldParas
, aNewParas
);
490 std::for_each(aOldParas
.begin(), aOldParas
.end(), ScChildGone(mpAccDoc
));
491 std::for_each(aNewParas
.begin(), aNewParas
.end(), ScChildNew(mpAccDoc
));
495 struct ScChangeOffset
498 ScChangeOffset(sal_Int32 nDiff
) : mnDiff(nDiff
) {}
499 void operator() (const ScAccNote
& rNote
)
501 if (rNote
.mpTextHelper
)
502 rNote
.mpTextHelper
->SetStartIndex(rNote
.mpTextHelper
->GetStartIndex() + mnDiff
);
506 void ScNotesChilds::SetOffset(sal_Int32 nNewOffset
)
508 sal_Int32
nDiff(nNewOffset
- mnOffset
);
511 std::for_each(maMarks
.begin(), maMarks
.end(), ScChangeOffset(nDiff
));
512 std::for_each(maNotes
.begin(), maNotes
.end(), ScChangeOffset(nDiff
));
513 mnOffset
= nNewOffset
;
517 inline ScDocument
* ScNotesChilds::GetDocument() const
519 ScDocument
* pDoc
= NULL
;
521 pDoc
= mpViewShell
->GetDocument();
525 class ScIAccessibleViewForwarder
: public ::accessibility::IAccessibleViewForwarder
528 ScIAccessibleViewForwarder();
529 ScIAccessibleViewForwarder(ScPreviewShell
* pViewShell
,
530 ScAccessibleDocumentPagePreview
* pAccDoc
,
531 const MapMode
& aMapMode
);
532 ~ScIAccessibleViewForwarder();
534 ///===== IAccessibleViewForwarder ========================================
536 virtual sal_Bool
IsValid (void) const;
537 virtual Rectangle
GetVisibleArea() const;
538 virtual Point
LogicToPixel (const Point
& rPoint
) const;
539 virtual Size
LogicToPixel (const Size
& rSize
) const;
540 virtual Point
PixelToLogic (const Point
& rPoint
) const;
541 virtual Size
PixelToLogic (const Size
& rSize
) const;
544 ScPreviewShell
* mpViewShell
;
545 ScAccessibleDocumentPagePreview
* mpAccDoc
;
550 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
555 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell
* pViewShell
,
556 ScAccessibleDocumentPagePreview
* pAccDoc
,
557 const MapMode
& aMapMode
)
558 : mpViewShell(pViewShell
),
565 ScIAccessibleViewForwarder::~ScIAccessibleViewForwarder()
569 ///===== IAccessibleViewForwarder ========================================
571 sal_Bool
ScIAccessibleViewForwarder::IsValid (void) const
577 Rectangle
ScIAccessibleViewForwarder::GetVisibleArea() const
581 Window
* pWin
= mpViewShell
->GetWindow();
584 aVisRect
.SetSize(pWin
->GetOutputSizePixel());
585 aVisRect
.SetPos(Point(0, 0));
587 aVisRect
= pWin
->PixelToLogic(aVisRect
, maMapMode
);
593 Point
ScIAccessibleViewForwarder::LogicToPixel (const Point
& rPoint
) const
597 Window
* pWin
= mpViewShell
->GetWindow();
598 if (pWin
&& mpAccDoc
)
600 Rectangle
aRect(mpAccDoc
->GetBoundingBoxOnScreen());
601 aPoint
= pWin
->LogicToPixel(rPoint
, maMapMode
) + aRect
.TopLeft();
607 Size
ScIAccessibleViewForwarder::LogicToPixel (const Size
& rSize
) const
611 Window
* pWin
= mpViewShell
->GetWindow();
613 aSize
= pWin
->LogicToPixel(rSize
, maMapMode
);
617 Point
ScIAccessibleViewForwarder::PixelToLogic (const Point
& rPoint
) const
621 Window
* pWin
= mpViewShell
->GetWindow();
622 if (pWin
&& mpAccDoc
)
624 Rectangle
aRect(mpAccDoc
->GetBoundingBoxOnScreen());
625 aPoint
= pWin
->PixelToLogic(rPoint
- aRect
.TopLeft(), maMapMode
);
630 Size
ScIAccessibleViewForwarder::PixelToLogic (const Size
& rSize
) const
634 Window
* pWin
= mpViewShell
->GetWindow();
636 aSize
= pWin
->PixelToLogic(rSize
, maMapMode
);
642 ScShapeChild() : mpAccShape(NULL
) {}
643 ScShapeChild(const ScShapeChild
& rOld
);
645 mutable ::accessibility::AccessibleShape
* mpAccShape
;
646 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> mxShape
;
650 ScShapeChild::ScShapeChild(const ScShapeChild
& rOld
)
652 mpAccShape(rOld
.mpAccShape
),
653 mxShape(rOld
.mxShape
),
654 mnRangeId(rOld
.mnRangeId
)
657 mpAccShape
->acquire();
660 ScShapeChild::~ScShapeChild()
664 mpAccShape
->dispose();
665 mpAccShape
->release();
669 struct ScShapeChildLess
671 sal_Bool
operator()(const ScShapeChild
& rChild1
, const ScShapeChild
& rChild2
) const
673 sal_Bool
bResult(sal_False
);
674 if (rChild1
.mxShape
.is() && rChild2
.mxShape
.is())
675 bResult
= (rChild1
.mxShape
.get() < rChild2
.mxShape
.get());
680 typedef std::vector
<ScShapeChild
> ScShapeChildVec
;
684 ScShapeChildVec maBackShapes
;
685 ScShapeChildVec maForeShapes
; // inclusive internal shapes
686 ScShapeChildVec maControls
;
687 Rectangle maPixelRect
;
689 ScIAccessibleViewForwarder maViewForwarder
;
692 typedef std::vector
<ScShapeRange
> ScShapeRangeVec
;
694 class ScShapeChilds
: public SfxListener
,
695 public ::accessibility::IAccessibleParent
698 ScShapeChilds(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
);
701 ///===== SfxListener =====================================================
703 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
);
705 ///===== IAccessibleParent ==============================================
707 virtual sal_Bool
ReplaceChild (
708 ::accessibility::AccessibleShape
* pCurrentChild
,
709 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
>& _rxShape
,
711 const ::accessibility::AccessibleShapeTreeInfo
& _rShapeTreeInfo
712 ) throw (::com::sun::star::uno::RuntimeException
);
714 ///===== Internal ========================================================
718 sal_Int32
GetBackShapeCount() const;
719 uno::Reference
<XAccessible
> GetBackShape(sal_Int32 nIndex
) const;
720 sal_Int32
GetForeShapeCount() const;
721 uno::Reference
<XAccessible
> GetForeShape(sal_Int32 nIndex
) const;
722 sal_Int32
GetControlCount() const;
723 uno::Reference
<XAccessible
> GetControl(sal_Int32 nIndex
) const;
724 uno::Reference
<XAccessible
> GetForegroundShapeAt(const awt::Point
& rPoint
) const; // inclusive controls
725 uno::Reference
<XAccessible
> GetBackgroundShapeAt(const awt::Point
& rPoint
) const;
728 void VisAreaChanged() const;
730 void SetDrawBroadcaster();
732 ScAccessibleDocumentPagePreview
* mpAccDoc
;
733 ScPreviewShell
* mpViewShell
;
734 ScShapeRangeVec maShapeRanges
;
736 void FindChanged(ScShapeChildVec
& aOld
, ScShapeChildVec
& aNew
) const;
737 void FindChanged(ScShapeRange
& aOld
, ScShapeRange
& aNew
) const;
738 ::accessibility::AccessibleShape
* GetAccShape(const ScShapeChild
& rShape
) const;
739 ::accessibility::AccessibleShape
* GetAccShape(const ScShapeChildVec
& rShapes
, sal_Int32 nIndex
) const;
740 void FillShapes(const Rectangle
& aPixelPaintRect
, const MapMode
& aMapMode
, sal_uInt8 nRangeId
);
741 //UNUSED2008-05 sal_Bool FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const;
743 // void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
744 // void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
745 SdrPage
* GetDrawPage() const;
748 ScShapeChilds::ScShapeChilds(ScPreviewShell
* pViewShell
, ScAccessibleDocumentPagePreview
* pAccDoc
)
751 mpViewShell(pViewShell
),
752 maShapeRanges(SC_PREVIEW_MAXRANGES
)
756 SfxBroadcaster
* pDrawBC
= pViewShell
->GetDocument()->GetDrawBroadcaster();
758 StartListening(*pDrawBC
);
762 ScShapeChilds::~ScShapeChilds()
766 SfxBroadcaster
* pDrawBC
= mpViewShell
->GetDocument()->GetDrawBroadcaster();
768 EndListening(*pDrawBC
);
772 void ScShapeChilds::SetDrawBroadcaster()
776 SfxBroadcaster
* pDrawBC
= mpViewShell
->GetDocument()->GetDrawBroadcaster();
778 StartListening(*pDrawBC
, TRUE
);
782 void ScShapeChilds::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
784 if ( rHint
.ISA( SdrHint
) )
786 const SdrHint
* pSdrHint
= PTR_CAST( SdrHint
, &rHint
);
789 SdrObject
* pObj
= const_cast<SdrObject
*>(pSdrHint
->GetObject());
790 if (pObj
&& (pObj
->GetPage() == GetDrawPage()))
792 switch (pSdrHint
->GetKind())
794 case HINT_OBJCHG
: // Objekt geaendert
798 // no longer necessary
799 /* case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
801 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
803 AddShape(xShape, pObj->GetLayer());
806 case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
808 uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
810 RemoveShape(xShape, pObj->GetLayer());
815 // other events are not interesting
824 void ScShapeChilds::FindChanged(ScShapeChildVec
& rOld
, ScShapeChildVec
& rNew
) const
826 ScShapeChildVec::iterator aOldItr
= rOld
.begin();
827 ScShapeChildVec::iterator aOldEnd
= rOld
.end();
828 ScShapeChildVec::const_iterator aNewItr
= rNew
.begin();
829 ScShapeChildVec::const_iterator aNewEnd
= rNew
.begin();
830 uno::Reference
<XAccessible
> xAcc
;
831 while ((aNewItr
!= aNewEnd
) && (aOldItr
!= aOldEnd
))
833 if (aNewItr
->mxShape
.get() == aOldItr
->mxShape
.get())
838 else if (aNewItr
->mxShape
.get() < aOldItr
->mxShape
.get())
840 xAcc
= GetAccShape(*aNewItr
);
841 AccessibleEventObject aEvent
;
842 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
843 aEvent
.EventId
= AccessibleEventId::CHILD
;
844 aEvent
.NewValue
<<= xAcc
;
845 mpAccDoc
->CommitChange(aEvent
);
850 xAcc
= GetAccShape(*aOldItr
);
851 AccessibleEventObject aEvent
;
852 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
853 aEvent
.EventId
= AccessibleEventId::CHILD
;
854 aEvent
.OldValue
<<= xAcc
;
855 mpAccDoc
->CommitChange(aEvent
);
859 while (aOldItr
!= aOldEnd
)
861 xAcc
= GetAccShape(*aOldItr
);
862 AccessibleEventObject aEvent
;
863 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
864 aEvent
.EventId
= AccessibleEventId::CHILD
;
865 aEvent
.OldValue
<<= xAcc
;
866 mpAccDoc
->CommitChange(aEvent
);
869 while (aNewItr
!= aNewEnd
)
871 xAcc
= GetAccShape(*aNewItr
);
872 AccessibleEventObject aEvent
;
873 aEvent
.Source
= uno::Reference
<XAccessibleContext
> (mpAccDoc
);
874 aEvent
.EventId
= AccessibleEventId::CHILD
;
875 aEvent
.NewValue
<<= xAcc
;
876 mpAccDoc
->CommitChange(aEvent
);
881 void ScShapeChilds::FindChanged(ScShapeRange
& rOld
, ScShapeRange
& rNew
) const
883 FindChanged(rOld
.maBackShapes
, rNew
.maBackShapes
);
884 FindChanged(rOld
.maForeShapes
, rNew
.maForeShapes
);
885 FindChanged(rOld
.maControls
, rNew
.maControls
);
888 void ScShapeChilds::DataChanged()
890 ScShapeRangeVec
aOldShapeRanges(maShapeRanges
);
891 maShapeRanges
.clear();
892 maShapeRanges
.resize(SC_PREVIEW_MAXRANGES
);
894 for (sal_Int32 i
= 0; i
< SC_PREVIEW_MAXRANGES
; ++i
)
896 FindChanged(aOldShapeRanges
[i
], maShapeRanges
[i
]);
900 struct ScVisAreaChanged
902 const ScIAccessibleViewForwarder
* mpViewForwarder
;
903 ScVisAreaChanged(const ScIAccessibleViewForwarder
* pViewForwarder
) : mpViewForwarder(pViewForwarder
) {}
904 void operator() (const ScShapeChild
& rAccShapeData
) const
906 if (rAccShapeData
.mpAccShape
)
908 rAccShapeData
.mpAccShape
->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA
, mpViewForwarder
);
913 void ScShapeChilds::VisAreaChanged() const
915 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
916 ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin();
917 while (aItr
!= aEndItr
)
919 ScVisAreaChanged
aVisAreaChanged(&(aItr
->maViewForwarder
));
920 std::for_each(aItr
->maBackShapes
.begin(), aItr
->maBackShapes
.end(), aVisAreaChanged
);
921 std::for_each(aItr
->maControls
.begin(), aItr
->maControls
.end(), aVisAreaChanged
);
922 std::for_each(aItr
->maForeShapes
.begin(), aItr
->maForeShapes
.end(), aVisAreaChanged
);
927 ///===== IAccessibleParent ==============================================
929 sal_Bool
ScShapeChilds::ReplaceChild (::accessibility::AccessibleShape
* /* pCurrentChild */,
930 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
>& /* _rxShape */,
931 const long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo
& /* _rShapeTreeInfo */)
932 throw (uno::RuntimeException
)
934 DBG_ERRORFILE("should not be called in the page preview");
938 ///===== Internal ========================================================
940 void ScShapeChilds::Init()
944 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
946 Rectangle aPixelPaintRect
;
948 sal_uInt16
nCount(rData
.GetDrawRanges());
949 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
951 rData
.GetDrawRange(i
, aPixelPaintRect
, aMapMode
, nRangeId
);
952 FillShapes(aPixelPaintRect
, aMapMode
, nRangeId
);
957 sal_Int32
ScShapeChilds::GetBackShapeCount() const
960 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
961 for ( ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin(); aItr
!= aEndItr
; ++aItr
)
962 nCount
+= aItr
->maBackShapes
.size();
966 uno::Reference
<XAccessible
> ScShapeChilds::GetBackShape(sal_Int32 nIndex
) const
968 uno::Reference
<XAccessible
> xAccessible
;
969 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
970 ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin();
971 while ((aItr
!= aEndItr
) && !xAccessible
.is())
973 sal_Int32
nCount(aItr
->maBackShapes
.size());
975 xAccessible
= GetAccShape(aItr
->maBackShapes
, nIndex
);
982 throw lang::IndexOutOfBoundsException();
987 sal_Int32
ScShapeChilds::GetForeShapeCount() const
990 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
991 for ( ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin(); aItr
!= aEndItr
; ++aItr
)
992 nCount
+= aItr
->maForeShapes
.size();
996 uno::Reference
<XAccessible
> ScShapeChilds::GetForeShape(sal_Int32 nIndex
) const
998 uno::Reference
<XAccessible
> xAccessible
;
999 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
1000 ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin();
1001 while ((aItr
!= aEndItr
) && !xAccessible
.is())
1003 sal_Int32
nCount(aItr
->maForeShapes
.size());
1005 xAccessible
= GetAccShape(aItr
->maForeShapes
, nIndex
);
1012 throw lang::IndexOutOfBoundsException();
1017 sal_Int32
ScShapeChilds::GetControlCount() const
1019 sal_Int32
nCount(0);
1020 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
1021 for ( ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin(); aItr
!= aEndItr
; ++aItr
)
1022 nCount
+= aItr
->maControls
.size();
1026 uno::Reference
<XAccessible
> ScShapeChilds::GetControl(sal_Int32 nIndex
) const
1028 uno::Reference
<XAccessible
> xAccessible
;
1029 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
1030 ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin();
1031 while ((aItr
!= aEndItr
) && !xAccessible
.is())
1033 sal_Int32
nCount(aItr
->maControls
.size());
1035 xAccessible
= GetAccShape(aItr
->maControls
, nIndex
);
1042 throw lang::IndexOutOfBoundsException();
1047 struct ScShapePointFound
1050 ScShapePointFound(const awt::Point
& rPoint
) : maPoint(VCLPoint(rPoint
)) {}
1051 sal_Bool
operator() (const ScShapeChild
& rShape
)
1053 sal_Bool
bResult(sal_False
);
1054 if ((VCLRectangle(rShape
.mpAccShape
->getBounds())).IsInside(maPoint
))
1060 uno::Reference
<XAccessible
> ScShapeChilds::GetForegroundShapeAt(const awt::Point
& rPoint
) const //inclusive Controls
1062 uno::Reference
<XAccessible
> xAcc
;
1064 ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin();
1065 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
1066 while((aItr
!= aEndItr
) && !xAcc
.is())
1068 ScShapeChildVec::const_iterator aFindItr
= std::find_if(aItr
->maForeShapes
.begin(), aItr
->maForeShapes
.end(), ScShapePointFound(rPoint
));
1069 if (aFindItr
!= aItr
->maForeShapes
.end())
1070 xAcc
= GetAccShape(*aFindItr
);
1073 ScShapeChildVec::const_iterator aCtrlItr
= std::find_if(aItr
->maControls
.begin(), aItr
->maControls
.end(), ScShapePointFound(rPoint
));
1074 if (aCtrlItr
!= aItr
->maControls
.end())
1075 xAcc
= GetAccShape(*aCtrlItr
);
1084 uno::Reference
<XAccessible
> ScShapeChilds::GetBackgroundShapeAt(const awt::Point
& rPoint
) const
1086 uno::Reference
<XAccessible
> xAcc
;
1088 ScShapeRangeVec::const_iterator aItr
= maShapeRanges
.begin();
1089 ScShapeRangeVec::const_iterator aEndItr
= maShapeRanges
.end();
1090 while((aItr
!= aEndItr
) && !xAcc
.is())
1092 ScShapeChildVec::const_iterator aFindItr
= std::find_if(aItr
->maBackShapes
.begin(), aItr
->maBackShapes
.end(), ScShapePointFound(rPoint
));
1093 if (aFindItr
!= aItr
->maBackShapes
.end())
1094 xAcc
= GetAccShape(*aFindItr
);
1102 ::accessibility::AccessibleShape
* ScShapeChilds::GetAccShape(const ScShapeChild
& rShape
) const
1104 if (!rShape
.mpAccShape
)
1106 ::accessibility::ShapeTypeHandler
& rShapeHandler
= ::accessibility::ShapeTypeHandler::Instance();
1107 ::accessibility::AccessibleShapeInfo
aShapeInfo(rShape
.mxShape
, mpAccDoc
, const_cast<ScShapeChilds
*>(this));
1111 ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo
;
1112 aShapeTreeInfo
.SetSdrView(mpViewShell
->GetPreview()->GetDrawView());
1113 aShapeTreeInfo
.SetController(NULL
);
1114 aShapeTreeInfo
.SetWindow(mpViewShell
->GetWindow());
1115 aShapeTreeInfo
.SetViewForwarder(&(maShapeRanges
[rShape
.mnRangeId
].maViewForwarder
));
1116 rShape
.mpAccShape
= rShapeHandler
.CreateAccessibleObject(aShapeInfo
, aShapeTreeInfo
);
1117 if (rShape
.mpAccShape
)
1119 rShape
.mpAccShape
->acquire();
1120 rShape
.mpAccShape
->Init();
1124 return rShape
.mpAccShape
;
1127 ::accessibility::AccessibleShape
* ScShapeChilds::GetAccShape(const ScShapeChildVec
& rShapes
, sal_Int32 nIndex
) const
1129 return (GetAccShape(rShapes
[nIndex
]));
1132 void ScShapeChilds::FillShapes(const Rectangle
& aPixelPaintRect
, const MapMode
& aMapMode
, sal_uInt8 nRangeId
)
1134 DBG_ASSERT(nRangeId
< maShapeRanges
.size(), "this is not a valid range for draw objects");
1135 SdrPage
* pPage
= GetDrawPage();
1136 Window
* pWin
= mpViewShell
->GetWindow();
1139 sal_Bool
bForeAdded(sal_False
);
1140 sal_Bool
bBackAdded(sal_False
);
1141 sal_Bool
bControlAdded(sal_False
);
1142 Rectangle
aClippedPixelPaintRect(aPixelPaintRect
);
1145 Rectangle
aRect2(Point(0,0), mpAccDoc
->GetBoundingBoxOnScreen().GetSize());
1146 aClippedPixelPaintRect
= aPixelPaintRect
.GetIntersection(aRect2
);
1148 maShapeRanges
[nRangeId
].maPixelRect
= aClippedPixelPaintRect
;
1149 maShapeRanges
[nRangeId
].maMapMode
= aMapMode
;
1150 ScIAccessibleViewForwarder
aViewForwarder(mpViewShell
, mpAccDoc
, aMapMode
);
1151 maShapeRanges
[nRangeId
].maViewForwarder
= aViewForwarder
;
1152 sal_uInt32
nCount(pPage
->GetObjCount());
1153 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
1155 SdrObject
* pObj
= pPage
->GetObj(i
);
1158 uno::Reference
< drawing::XShape
> xShape(pObj
->getUnoShape(), uno::UNO_QUERY
);
1161 Rectangle
aRect(pWin
->LogicToPixel(VCLPoint(xShape
->getPosition()), aMapMode
), pWin
->LogicToPixel(VCLSize(xShape
->getSize()), aMapMode
));
1162 if(!aClippedPixelPaintRect
.GetIntersection(aRect
).IsEmpty())
1164 ScShapeChild aShape
;
1165 aShape
.mxShape
= xShape
;
1166 aShape
.mnRangeId
= nRangeId
;
1167 switch (pObj
->GetLayer())
1169 case SC_LAYER_INTERN
:
1170 case SC_LAYER_FRONT
:
1172 maShapeRanges
[nRangeId
].maForeShapes
.push_back(aShape
);
1173 bForeAdded
= sal_True
;
1178 maShapeRanges
[nRangeId
].maBackShapes
.push_back(aShape
);
1179 bBackAdded
= sal_True
;
1182 case SC_LAYER_CONTROLS
:
1184 maShapeRanges
[nRangeId
].maControls
.push_back(aShape
);
1185 bControlAdded
= sal_True
;
1190 DBG_ERRORFILE("I don't know this layer.");
1199 std::sort(maShapeRanges
[nRangeId
].maForeShapes
.begin(), maShapeRanges
[nRangeId
].maForeShapes
.end(),ScShapeChildLess());
1201 std::sort(maShapeRanges
[nRangeId
].maBackShapes
.begin(), maShapeRanges
[nRangeId
].maBackShapes
.end(),ScShapeChildLess());
1203 std::sort(maShapeRanges
[nRangeId
].maControls
.begin(), maShapeRanges
[nRangeId
].maControls
.end(),ScShapeChildLess());
1207 //UNUSED2008-05 sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const
1209 //UNUSED2008-05 sal_Bool bResult(sal_False);
1210 //UNUSED2008-05 ScShapeChild aShape;
1211 //UNUSED2008-05 aShape.mxShape = xShape;
1212 //UNUSED2008-05 rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess());
1213 //UNUSED2008-05 if (rItr->mxShape.get() == xShape.get())
1214 //UNUSED2008-05 bResult = sal_True; // if the shape is found
1216 //UNUSED2008-05 /*#ifndef PRODUCT // test whether it finds truly the correct shape (perhaps it is not really sorted)
1217 //UNUSED2008-05 ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape);
1218 //UNUSED2008-05 DBG_ASSERT(rItr == aDebugItr, "wrong Shape found");
1219 //UNUSED2008-05 #endif*/
1220 //UNUSED2008-05 return bResult;
1223 /*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
1225 uno::Reference < XAccessible > xNew;
1226 Window* pWin = mpViewShell->GetWindow();
1229 ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
1230 ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
1231 sal_Bool bNotify(sal_False);
1232 uno::Reference <XAccessible> xAcc;
1233 while (aItr != aEndItr)
1235 Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode));
1236 Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize()));
1237 if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty())
1239 ScShapeChild aShape;
1240 aShape.mxShape = xShape;
1243 case SC_LAYER_INTERN:
1244 case SC_LAYER_FRONT:
1247 aItr->maForeShapes.push_back(aShape);
1248 std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess());
1254 aItr->maBackShapes.push_back(aShape);
1255 std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess());
1258 case SC_LAYER_CONTROLS:
1261 aItr->maControls.push_back(aShape);
1262 std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess());
1267 DBG_ERRORFILE("I don't know this layer.");
1273 xAcc = GetAccShape(aShape);
1274 AccessibleEventObject aEvent;
1275 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
1276 aEvent.EventId = AccessibleEventId::CHILD;
1277 aEvent.NewValue <<= xAcc;
1278 mpAccDoc->CommitChange(aEvent);
1279 bNotify = sal_False;
1288 /*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr)
1290 sal_Bool bResult(sal_False);
1291 if (aItr->mpAccShape)
1294 xAcc = aItr->mpAccShape;
1297 DBG_ERRORFILE("No Accessible object found. Don't know how to notify.");
1301 /*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
1303 ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
1304 ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
1305 ScShapeChildVec::iterator aEraseItr;
1306 sal_Bool bNotify(sal_False);
1307 uno::Reference <XAccessible> xAcc;
1308 while (aItr != aEndItr)
1312 case SC_LAYER_INTERN:
1313 case SC_LAYER_FRONT:
1315 if (FindShape(aItr->maForeShapes, xShape, aEraseItr))
1317 bNotify = HaveToNotify(xAcc, aEraseItr);
1318 aItr->maForeShapes.erase(aEraseItr);
1324 if (FindShape(aItr->maBackShapes, xShape, aEraseItr))
1326 bNotify = HaveToNotify(xAcc, aEraseItr);
1327 aItr->maBackShapes.erase(aEraseItr);
1331 case SC_LAYER_CONTROLS:
1333 if (FindShape(aItr->maControls, xShape, aEraseItr))
1335 bNotify = HaveToNotify(xAcc, aEraseItr);
1336 aItr->maControls.erase(aEraseItr);
1342 DBG_ERRORFILE("I don't know this layer.");
1348 AccessibleEventObject aEvent;
1349 aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
1350 aEvent.EventId = AccessibleEventId::CHILD;
1351 aEvent.OldValue <<= xAcc;
1352 mpAccDoc->CommitChange(aEvent);
1353 bNotify = sal_False;
1360 SdrPage
* ScShapeChilds::GetDrawPage() const
1362 SCTAB
nTab( mpViewShell
->GetLocationData().GetPrintTab() );
1363 SdrPage
* pDrawPage
= NULL
;
1366 ScDocument
* pDoc
= mpViewShell
->GetDocument();
1367 if (pDoc
&& pDoc
->GetDrawLayer())
1369 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
1370 if (pDrawLayer
->HasObjects() && (pDrawLayer
->GetPageCount() > nTab
))
1371 pDrawPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(static_cast<sal_Int16
>(nTab
)));
1377 struct ScPagePreviewCountData
1379 // order is background shapes, header, table or notes, footer, foreground shapes, controls
1385 long nNoteParagraphs
;
1390 ScPagePreviewCountData( const ScPreviewLocationData
& rData
, Window
* pSizeWindow
,
1391 ScNotesChilds
* pNotesChilds
, ScShapeChilds
* pShapeChilds
);
1393 long GetTotal() const
1395 return nBackShapes
+ nHeaders
+ nTables
+ nNoteParagraphs
+ nFooters
+ nForeShapes
+ nControls
;
1399 ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData
& rData
,
1400 Window
* pSizeWindow
, ScNotesChilds
* pNotesChilds
,
1401 ScShapeChilds
* pShapeChilds
) :
1405 nNoteParagraphs( 0 ),
1412 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1414 aVisRect
= Rectangle( aPoint
, aOutputSize
);
1418 if ( rData
.GetHeaderPosition( aObjRect
) && aObjRect
.IsOver( aVisRect
) )
1421 if ( rData
.GetFooterPosition( aObjRect
) && aObjRect
.IsOver( aVisRect
) )
1424 if ( rData
.HasCellsInRange( aVisRect
) )
1428 nBackShapes
= pShapeChilds
->GetBackShapeCount();
1429 nForeShapes
= pShapeChilds
->GetForeShapeCount();
1430 nControls
= pShapeChilds
->GetControlCount();
1432 // there are only notes if there is no table
1434 nNoteParagraphs
= pNotesChilds
->GetChildsCount();
1437 //===== internal ========================================================
1439 ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
1440 const uno::Reference
<XAccessible
>& rxParent
, ScPreviewShell
* pViewShell
) :
1441 ScAccessibleDocumentBase(rxParent
),
1442 mpViewShell(pViewShell
),
1443 mpNotesChilds(NULL
),
1444 mpShapeChilds(NULL
),
1450 pViewShell
->AddAccessibilityObject(*this);
1452 // GetNotesChilds(); not neccessary and reduces the creation performance
1453 // GetShapeChilds();
1456 ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void)
1458 if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper
.bInDispose
)
1460 // increment refcount to prevent double call off dtor
1461 osl_incrementInterlockedCount( &m_refCount
);
1462 // call dispose to inform object wich have a weak reference to this object
1467 void SAL_CALL
ScAccessibleDocumentPagePreview::disposing()
1477 mpHeader
->release();
1482 mpFooter
->release();
1488 mpViewShell
->RemoveAccessibilityObject(*this);
1492 // #100593# no need to Dispose the AccessibleTextHelper,
1493 // as long as mpNotesChilds are destructed here
1495 DELETEZ(mpNotesChilds
);
1498 DELETEZ(mpShapeChilds
);
1500 ScAccessibleDocumentBase::disposing();
1503 //===== SfxListener =====================================================
1505 void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1507 if (rHint
.ISA( SfxSimpleHint
) )
1509 const SfxSimpleHint
& rRef
= (const SfxSimpleHint
&)rHint
;
1510 // only notify if child exist, otherwise it is not necessary
1511 if ((rRef
.GetId() == SC_HINT_DATACHANGED
))
1513 if (mpTable
) // if there is no table there is nothing to notify, because no one recongnizes the change
1516 uno::Reference
<XAccessible
> xAcc
= mpTable
;
1517 AccessibleEventObject aEvent
;
1518 aEvent
.EventId
= AccessibleEventId::CHILD
;
1519 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1520 aEvent
.OldValue
<<= xAcc
;
1521 CommitChange(aEvent
);
1530 Window
* pSizeWindow
= mpViewShell
->GetWindow();
1532 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1534 Rectangle
aVisRect( aPoint
, aOutputSize
);
1535 GetNotesChilds()->DataChanged(aVisRect
);
1537 GetShapeChilds()->DataChanged();
1539 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1540 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1542 if (aCount
.nTables
> 0)
1544 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1545 sal_Int32
nIndex (aCount
.nBackShapes
+ aCount
.nHeaders
);
1547 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1552 uno::Reference
<XAccessible
> xAcc
= mpTable
;
1553 AccessibleEventObject aEvent
;
1554 aEvent
.EventId
= AccessibleEventId::CHILD
;
1555 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1556 aEvent
.NewValue
<<= xAcc
;
1557 CommitChange(aEvent
);
1561 else if (rRef
.GetId() == SC_HINT_ACC_MAKEDRAWLAYER
)
1563 GetShapeChilds()->SetDrawBroadcaster();
1565 else if (rRef
.GetId() == SC_HINT_ACC_VISAREACHANGED
)
1568 Window
* pSizeWindow
= mpViewShell
->GetWindow();
1570 aOutputSize
= pSizeWindow
->GetOutputSizePixel();
1572 Rectangle
aVisRect( aPoint
, aOutputSize
);
1573 GetNotesChilds()->DataChanged(aVisRect
);
1575 GetShapeChilds()->VisAreaChanged();
1577 AccessibleEventObject aEvent
;
1578 aEvent
.EventId
= AccessibleEventId::VISIBLE_DATA_CHANGED
;
1579 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
1580 CommitChange(aEvent
);
1583 else if ( rHint
.ISA(ScAccWinFocusLostHint
) )
1587 else if ( rHint
.ISA(ScAccWinFocusGotHint
) )
1589 CommitFocusGained();
1591 ScAccessibleDocumentBase::Notify(rBC
, rHint
);
1594 //===== XAccessibleComponent ============================================
1596 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point
& rPoint
)
1597 throw (uno::RuntimeException
)
1599 uno::Reference
<XAccessible
> xAccessible
;
1600 if (containsPoint(rPoint
))
1607 xAccessible
= GetShapeChilds()->GetForegroundShapeAt(rPoint
);
1608 if (!xAccessible
.is())
1610 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1611 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1613 /* if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) )
1615 if ( !mpTable && (aCount.nTables > 0) )
1617 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1618 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1620 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1624 xAccessible = mpTable;
1626 if ( !mpTable
&& (aCount
.nTables
> 0) )
1628 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1629 sal_Int32
nIndex (aCount
.nBackShapes
+ aCount
.nHeaders
);
1631 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1635 if (mpTable
&& VCLRectangle(mpTable
->getBounds()).IsInside(VCLPoint(rPoint
)))
1636 xAccessible
= mpTable
;
1638 if (!xAccessible
.is())
1639 xAccessible
= GetNotesChilds()->GetAt(rPoint
);
1640 if (!xAccessible
.is())
1642 if (!mpHeader
|| !mpFooter
)
1644 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1645 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1649 mpHeader
= new ScAccessiblePageHeader( this, mpViewShell
, sal_True
, aCount
.nBackShapes
+ aCount
.nHeaders
- 1);
1650 mpHeader
->acquire();
1654 mpFooter
= new ScAccessiblePageHeader( this, mpViewShell
, sal_False
, aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
- 1 );
1655 mpFooter
->acquire();
1659 Point
aPoint(VCLPoint(rPoint
));
1661 if (VCLRectangle(mpHeader
->getBounds()).IsInside(aPoint
))
1662 xAccessible
= mpHeader
;
1663 else if (VCLRectangle(mpFooter
->getBounds()).IsInside(aPoint
))
1664 xAccessible
= mpFooter
;
1666 if (!xAccessible
.is())
1667 xAccessible
= GetShapeChilds()->GetBackgroundShapeAt(rPoint
);
1674 void SAL_CALL
ScAccessibleDocumentPagePreview::grabFocus() throw (uno::RuntimeException
)
1678 if (getAccessibleParent().is())
1680 uno::Reference
<XAccessibleComponent
> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY
);
1681 if (xAccessibleComponent
.is())
1683 // just grab the focus for the window
1684 xAccessibleComponent
->grabFocus();
1689 //===== XAccessibleContext ==============================================
1691 sal_Int32 SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleChildCount(void) throw (uno::RuntimeException
)
1699 ScPagePreviewCountData
aCount( mpViewShell
->GetLocationData(), mpViewShell
->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1700 nRet
= aCount
.GetTotal();
1706 uno::Reference
<XAccessible
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex
)
1707 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
1711 uno::Reference
<XAccessible
> xAccessible
;
1715 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1716 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1718 if ( nIndex
< aCount
.nBackShapes
)
1720 xAccessible
= GetShapeChilds()->GetBackShape(nIndex
);
1722 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
)
1726 mpHeader
= new ScAccessiblePageHeader( this, mpViewShell
, sal_True
, nIndex
);
1727 mpHeader
->acquire();
1730 xAccessible
= mpHeader
;
1732 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
)
1736 mpTable
= new ScAccessiblePreviewTable( this, mpViewShell
, nIndex
);
1740 xAccessible
= mpTable
;
1742 else if ( nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nNoteParagraphs
)
1744 xAccessible
= GetNotesChilds()->GetChild(nIndex
- aCount
.nBackShapes
- aCount
.nHeaders
);
1746 else if ( (nIndex
< aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
) )
1750 mpFooter
= new ScAccessiblePageHeader( this, mpViewShell
, sal_False
, nIndex
);
1751 mpFooter
->acquire();
1753 xAccessible
= mpFooter
;
1757 sal_Int32
nIdx(nIndex
- (aCount
.nBackShapes
+ aCount
.nHeaders
+ aCount
.nTables
+ aCount
.nNoteParagraphs
+ aCount
.nFooters
));
1758 if (nIdx
< aCount
.nForeShapes
)
1759 xAccessible
= GetShapeChilds()->GetForeShape(nIdx
);
1761 xAccessible
= GetShapeChilds()->GetControl(nIdx
- aCount
.nForeShapes
);
1765 if ( !xAccessible
.is() )
1766 throw lang::IndexOutOfBoundsException();
1771 /// Return the set of current states.
1772 uno::Reference
<XAccessibleStateSet
> SAL_CALL
ScAccessibleDocumentPagePreview::getAccessibleStateSet(void)
1773 throw (uno::RuntimeException
)
1776 uno::Reference
<XAccessibleStateSet
> xParentStates
;
1777 if (getAccessibleParent().is())
1779 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
1780 xParentStates
= xParentContext
->getAccessibleStateSet();
1782 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
1783 if (IsDefunc(xParentStates
))
1784 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
1788 pStateSet
->AddState(AccessibleStateType::ENABLED
);
1789 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
1791 pStateSet
->AddState(AccessibleStateType::SHOWING
);
1793 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
1798 //===== XServiceInfo ====================================================
1800 ::rtl::OUString SAL_CALL
ScAccessibleDocumentPagePreview::getImplementationName(void)
1801 throw (uno::RuntimeException
)
1803 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview"));
1806 uno::Sequence
< ::rtl::OUString
> SAL_CALL
ScAccessibleDocumentPagePreview::getSupportedServiceNames(void)
1807 throw (uno::RuntimeException
)
1809 uno::Sequence
< ::rtl::OUString
> aSequence
= ScAccessibleContextBase::getSupportedServiceNames();
1810 sal_Int32
nOldSize(aSequence
.getLength());
1811 aSequence
.realloc(nOldSize
+ 1);
1812 ::rtl::OUString
* pNames
= aSequence
.getArray();
1814 pNames
[nOldSize
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView"));
1819 //===== XTypeProvider =======================================================
1821 uno::Sequence
<sal_Int8
> SAL_CALL
1822 ScAccessibleDocumentPagePreview::getImplementationId(void)
1823 throw (uno::RuntimeException
)
1827 static uno::Sequence
<sal_Int8
> aId
;
1828 if (aId
.getLength() == 0)
1831 rtl_createUuid (reinterpret_cast<sal_uInt8
*>(aId
.getArray()), 0, sal_True
);
1836 //===== internal ========================================================
1838 ::rtl::OUString SAL_CALL
ScAccessibleDocumentPagePreview::createAccessibleDescription(void)
1839 throw (uno::RuntimeException
)
1841 rtl::OUString sDescription
= String(ScResId(STR_ACC_PREVIEWDOC_DESCR
));
1842 return sDescription
;
1845 ::rtl::OUString SAL_CALL
ScAccessibleDocumentPagePreview::createAccessibleName(void)
1846 throw (uno::RuntimeException
)
1848 rtl::OUString sName
= String(ScResId(STR_ACC_PREVIEWDOC_NAME
));
1852 Rectangle
ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const throw (uno::RuntimeException
)
1857 Window
* pWindow
= mpViewShell
->GetWindow();
1859 aRect
= pWindow
->GetWindowExtentsRelative(NULL
);
1864 Rectangle
ScAccessibleDocumentPagePreview::GetBoundingBox() const throw (uno::RuntimeException
)
1869 Window
* pWindow
= mpViewShell
->GetWindow();
1871 aRect
= pWindow
->GetWindowExtentsRelative(pWindow
->GetAccessibleParentWindow());
1876 sal_Bool
ScAccessibleDocumentPagePreview::IsDefunc(
1877 const uno::Reference
<XAccessibleStateSet
>& rxParentStates
)
1879 return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
1880 (rxParentStates
.is() && rxParentStates
->contains(AccessibleStateType::DEFUNC
));
1883 ScNotesChilds
* ScAccessibleDocumentPagePreview::GetNotesChilds()
1885 if (!mpNotesChilds
&& mpViewShell
)
1887 mpNotesChilds
= new ScNotesChilds(mpViewShell
, this);
1889 const ScPreviewLocationData
& rData
= mpViewShell
->GetLocationData();
1890 ScPagePreviewCountData
aCount( rData
, mpViewShell
->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1892 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1893 mpNotesChilds
->Init(aCount
.aVisRect
, aCount
.nBackShapes
+ aCount
.nHeaders
);
1895 return mpNotesChilds
;
1898 ScShapeChilds
* ScAccessibleDocumentPagePreview::GetShapeChilds()
1900 if (!mpShapeChilds
&& mpViewShell
)
1902 mpShapeChilds
= new ScShapeChilds(mpViewShell
, this);
1903 mpShapeChilds
->Init();
1906 return mpShapeChilds
;
1909 //UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable()
1911 //UNUSED2009-05 if (!mpTable)
1913 //UNUSED2009-05 if ( mpViewShell )
1915 //UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1916 //UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1917 //UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1918 //UNUSED2009-05 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1920 //UNUSED2009-05 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1921 //UNUSED2009-05 mpTable->acquire();
1922 //UNUSED2009-05 mpTable->Init();
1925 //UNUSED2009-05 return mpTable;
1928 //UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged()
1930 //UNUSED2009-05 if (mpViewShell)
1932 //UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1933 //UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1934 //UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1935 //UNUSED2009-05 if(mpHeader)
1936 //UNUSED2009-05 mpHeader->SetCurrentIndexInParent(aCount.nBackShapes);
1937 //UNUSED2009-05 if (mpTable)
1938 //UNUSED2009-05 mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders);
1939 //UNUSED2009-05 if (mpFooter)
1940 //UNUSED2009-05 mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs);
1942 //UNUSED2009-05 if (mpNotesChilds)
1943 //UNUSED2009-05 mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders);