1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #include "AccessibleDocumentPagePreview.hxx"
32 #include "AccessiblePreviewTable.hxx"
33 #include "AccessiblePageHeader.hxx"
34 #include "AccessibilityHints.hxx"
35 #include "AccessibleText.hxx"
36 #include "document.hxx"
37 #include "prevwsh.hxx"
38 #include "prevloc.hxx"
39 #include "unoguard.hxx"
40 #include "drwlayer.hxx"
41 #include "editsrc.hxx"
42 #include "scresid.hxx"
43 #include "sc.hrc"
44 #include "DrawModelBroadcaster.hxx"
45 #include "docsh.hxx"
46 #include "drawview.hxx"
47 #include "preview.hxx"
48 #include "postit.hxx"
49 
50 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
51 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
52 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
53 
54 #include <unotools/accessiblestatesethelper.hxx>
55 #include <tools/debug.hxx>
56 #include <tools/gen.hxx>
57 #include <svx/svdpage.hxx>
58 #include <svx/svdobj.hxx>
59 #include <svx/AccessibleTextHelper.hxx>
60 #include <svx/AccessibleShape.hxx>
61 #include <svx/ShapeTypeHandler.hxx>
62 #include <toolkit/helper/convert.hxx>
63 #include <svx/unoshape.hxx>
64 #include <unotools/accessiblerelationsethelper.hxx>
65 
66 #include <vector>
67 #include <list>
68 #include <algorithm>
69 #include <memory>
70 
71 using namespace	::com::sun::star;
72 using namespace	::com::sun::star::accessibility;
73 
74 //=========================================================================
75 
76 typedef std::list< uno::Reference< XAccessible > > ScXAccList;
77 
78 
79 struct ScAccNote
80 {
81     String      maNoteText;
82     Rectangle   maRect;
83     ScAddress   maNoteCell;
84     ::accessibility::AccessibleTextHelper* mpTextHelper;
85     sal_Int32   mnParaCount;
86     sal_Bool    mbMarkNote;
87 
88                 ScAccNote() : mpTextHelper(NULL), mnParaCount(0) {}
89 };
90 
91 class ScNotesChilds
92 {
93 public:
94     ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
95     ~ScNotesChilds();
96     void Init(const Rectangle& rVisRect, sal_Int32 nOffset);
97 
98     sal_Int32 GetChildsCount() const;
99     uno::Reference<XAccessible> GetChild(sal_Int32 nIndex) const;
100     uno::Reference<XAccessible> GetAt(const awt::Point& rPoint) const;
101 
102     void DataChanged(const Rectangle& rVisRect);
103     void SetOffset(sal_Int32 nNewOffset);
104 private:
105     ScPreviewShell*         mpViewShell;
106     ScAccessibleDocumentPagePreview* mpAccDoc;
107     typedef std::vector<ScAccNote> ScAccNotes;
108     mutable ScAccNotes      maNotes;
109     mutable ScAccNotes      maMarks;
110     sal_Int32               mnParagraphs;
111     sal_Int32               mnOffset;
112 
113     ::accessibility::AccessibleTextHelper* CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const;
114     sal_Int32 AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes);
115 
116     sal_Int8 CompareCell(const ScAddress& aCell1, const ScAddress& aCell2);
117     void CollectChilds(const ScAccNote& rNote, ScXAccList& rList);
118     sal_Int32 CheckChanges(const ScPreviewLocationData& rData, const Rectangle& rVisRect,
119         sal_Bool bMark, ScAccNotes& rOldNotes, ScAccNotes& rNewNotes,
120         ScXAccList& rOldParas, ScXAccList& rNewParas);
121 
122     inline ScDocument* GetDocument() const;
123 };
124 
125 ScNotesChilds::ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
126     : mpViewShell(pViewShell),
127     mpAccDoc(pAccDoc),
128     mnParagraphs(0),
129     mnOffset(0)
130 {
131 }
132 
133 struct DeleteAccNote
134 {
135     void operator()(ScAccNote& rNote)
136     {
137         if (rNote.mpTextHelper)
138             DELETEZ( rNote.mpTextHelper);
139     }
140 };
141 
142 ScNotesChilds::~ScNotesChilds()
143 {
144     std::for_each(maNotes.begin(), maNotes.end(), DeleteAccNote());
145     std::for_each(maMarks.begin(), maMarks.end(), DeleteAccNote());
146 }
147 
148 ::accessibility::AccessibleTextHelper* ScNotesChilds::CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const
149 {
150     ::accessibility::AccessibleTextHelper* pTextHelper = NULL;
151 
152     ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
153 		(new ScAccessibleNoteTextData(mpViewShell, rString, aCellPos, bMarkNote));
154 	::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
155 
156 	pTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource);
157 
158     if (pTextHelper)
159     {
160         pTextHelper->SetEventSource(mpAccDoc);
161         pTextHelper->SetStartIndex(nChildOffset);
162         pTextHelper->SetOffset(rVisRect.TopLeft());
163     }
164 
165     return pTextHelper;
166 }
167 
168 sal_Int32 ScNotesChilds::AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes)
169 {
170     sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
171 
172     rNotes.reserve(nCount);
173 
174     sal_Int32 nParagraphs(0);
175     ScDocument* pDoc = GetDocument();
176     if (pDoc)
177     {
178         ScAccNote aNote;
179         aNote.mbMarkNote = bMark;
180         if (bMark)
181             aNote.mnParaCount = 1;
182         for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
183         {
184             if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
185             {
186                 if (bMark)
187                 {
188 	                // Document not needed, because only the cell address, but not the tablename is needed
189 	                aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
190                 }
191                 else
192                 {
193                     if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
194                         aNote.maNoteText = pNote->GetText();
195                     aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
196                     if (aNote.mpTextHelper)
197                         aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
198                 }
199                 nParagraphs += aNote.mnParaCount;
200                 rNotes.push_back(aNote);
201             }
202         }
203     }
204     return nParagraphs;
205 }
206 
207 void ScNotesChilds::Init(const Rectangle& rVisRect, sal_Int32 nOffset)
208 {
209     if (mpViewShell && !mnParagraphs)
210     {
211         mnOffset = nOffset;
212         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
213 
214         mnParagraphs = AddNotes(rData, rVisRect, sal_False, maMarks);
215         mnParagraphs += AddNotes(rData, rVisRect, sal_True, maNotes);
216     }
217 }
218 
219 sal_Int32 ScNotesChilds::GetChildsCount() const
220 {
221     return mnParagraphs;
222 }
223 
224 struct ScParaFound
225 {
226     sal_Int32 mnIndex;
227     ScParaFound(sal_Int32 nIndex) : mnIndex(nIndex) {}
228     sal_Bool operator() (const ScAccNote& rNote)
229     {
230         sal_Bool bResult(sal_False);
231         if (rNote.mnParaCount > mnIndex)
232             bResult = sal_True;
233         else
234             mnIndex -= rNote.mnParaCount;
235         return bResult;
236     }
237 };
238 
239 uno::Reference<XAccessible> ScNotesChilds::GetChild(sal_Int32 nIndex) const
240 {
241     uno::Reference<XAccessible> xAccessible;
242 
243     if (nIndex < mnParagraphs)
244     {
245         if (nIndex < static_cast<sal_Int32>(maMarks.size()))
246         {
247             ScAccNotes::iterator aEndItr = maMarks.end();
248             ScParaFound aParaFound(nIndex);
249             ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aParaFound);
250             if (aItr != aEndItr)
251             {
252                 DBG_ASSERT((aItr->maNoteCell == maMarks[nIndex].maNoteCell) && (aItr->mbMarkNote == maMarks[nIndex].mbMarkNote), "wrong note found");
253             }
254             else
255             {
256                 DBG_ERRORFILE("wrong note found");
257             }
258             if (!aItr->mpTextHelper)
259                 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
260             xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
261         }
262         else
263         {
264             nIndex -= maMarks.size();
265             ScAccNotes::iterator aEndItr = maNotes.end();
266             ScParaFound aParaFound(nIndex);
267             ScAccNotes::iterator aItr = std::find_if(maNotes.begin(), aEndItr, aParaFound);
268             if (aEndItr != aItr)
269             {
270                 if (!aItr->mpTextHelper)
271                     aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, (nIndex - aParaFound.mnIndex) + mnOffset + maMarks.size());
272                 xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
273             }
274         }
275     }
276 
277     return xAccessible;
278 }
279 
280 struct ScPointFound
281 {
282     Rectangle maPoint;
283     sal_Int32 mnParagraphs;
284     ScPointFound(const Point& rPoint) : maPoint(rPoint, Size(0, 0)), mnParagraphs(0) {}
285     sal_Bool operator() (const ScAccNote& rNote)
286     {
287         sal_Bool bResult(sal_False);
288         if (maPoint.IsInside(rNote.maRect))
289             bResult = sal_True;
290         else
291             mnParagraphs += rNote.mnParaCount;
292         return bResult;
293     }
294 };
295 
296 uno::Reference<XAccessible> ScNotesChilds::GetAt(const awt::Point& rPoint) const
297 {
298     uno::Reference<XAccessible> xAccessible;
299 
300     ScPointFound aPointFound(Point(rPoint.X, rPoint.Y));
301 
302     ScAccNotes::iterator aEndItr = maMarks.end();
303     ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aPointFound);
304     if (aEndItr == aItr)
305     {
306         aEndItr = maNotes.end();
307         aItr = std::find_if(maNotes.begin(), aEndItr, aPointFound);
308     }
309     if (aEndItr != aItr)
310     {
311         if (!aItr->mpTextHelper)
312             aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, aPointFound.mnParagraphs + mnOffset);
313         xAccessible = aItr->mpTextHelper->GetAt(rPoint);
314     }
315 
316     return xAccessible;
317 }
318 
319 sal_Int8 ScNotesChilds::CompareCell(const ScAddress& aCell1, const ScAddress& aCell2)
320 {
321     DBG_ASSERT(aCell1.Tab() == aCell2.Tab(), "the notes should be on the same table");
322     sal_Int8 nResult(0);
323     if (aCell1 != aCell2)
324     {
325         if (aCell1.Row() == aCell2.Row())
326             nResult = (aCell1.Col() < aCell2.Col()) ? -1 : 1;
327         else
328             nResult = (aCell1.Row() < aCell2.Row()) ? -1 : 1;
329     }
330     return nResult;
331 }
332 
333 void ScNotesChilds::CollectChilds(const ScAccNote& rNote, ScXAccList& rList)
334 {
335     if (rNote.mpTextHelper)
336         for (sal_Int32 i = 0; i < rNote.mnParaCount; ++i)
337             rList.push_back(rNote.mpTextHelper->GetChild(i + rNote.mpTextHelper->GetStartIndex()));
338 }
339 
340 sal_Int32 ScNotesChilds::CheckChanges(const ScPreviewLocationData& rData,
341             const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rOldNotes,
342             ScAccNotes& rNewNotes, ScXAccList& rOldParas, ScXAccList& rNewParas)
343 {
344     sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
345 
346     rNewNotes.reserve(nCount);
347 
348     sal_Int32 nParagraphs(0);
349     ScDocument* pDoc = GetDocument();
350     if (pDoc)
351     {
352         ScAccNote aNote;
353         aNote.mbMarkNote = bMark;
354         if (bMark)
355             aNote.mnParaCount = 1;
356         ScAccNotes::iterator aItr = rOldNotes.begin();
357         ScAccNotes::iterator aEndItr = rOldNotes.end();
358         sal_Bool bAddNote(sal_False);
359         for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
360         {
361             if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
362             {
363                 if (bMark)
364                 {
365 	                // Document not needed, because only the cell address, but not the tablename is needed
366 	                aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
367                 }
368                 else
369                 {
370                     if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
371                         aNote.maNoteText = pNote->GetText();
372                 }
373 
374                 sal_Int8 nCompare(-1); // if there are no more old childs it is always a new one
375                 if (aItr != aEndItr)
376                     nCompare = CompareCell(aNote.maNoteCell, aItr->maNoteCell);
377                 if (nCompare == 0)
378                 {
379                     if (aNote.maNoteText == aItr->maNoteText)
380                     {
381                         aNote.mpTextHelper = aItr->mpTextHelper;
382                         if (aNote.maRect != aItr->maRect)  //neue VisArea setzen
383                         {
384                             aNote.mpTextHelper->SetOffset(aNote.maRect.TopLeft());
385                             aNote.mpTextHelper->UpdateChildren();
386                             //DBG_ASSERT(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
387                             // could be changed, because only a part of the note is visible
388                         }
389                     }
390                     else
391                     {
392                         aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
393                         if (aNote.mpTextHelper)
394                             aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
395                         // collect removed childs
396                         CollectChilds(*aItr, rOldParas);
397                         DELETEZ(aItr->mpTextHelper);
398                         // collect new childs
399                         CollectChilds(aNote, rNewParas);
400                     }
401                     bAddNote = sal_True;
402                     // not necessary, because this branch should not be reached if it is the end
403                     //if (aItr != aEndItr)
404                     ++aItr;
405                 }
406                 else if (nCompare < 0)
407                 {
408                     aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
409                     if (aNote.mpTextHelper)
410                         aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
411                     // collect new childs
412                     CollectChilds(aNote, rNewParas);
413                     bAddNote = sal_True;
414                 }
415                 else
416                 {
417                     // collect removed childs
418                     CollectChilds(*aItr, rOldParas);
419                     DELETEZ(aItr->mpTextHelper);
420 
421                     // no note to add
422                     // not necessary, because this branch should not be reached if it is the end
423                     //if (aItr != aEndItr)
424                     ++aItr;
425                 }
426                 if (bAddNote)
427                 {
428                     nParagraphs += aNote.mnParaCount;
429                     rNewNotes.push_back(aNote);
430                     bAddNote = sal_False;
431                 }
432             }
433         }
434     }
435     return nParagraphs;
436 }
437 
438 struct ScChildGone
439 {
440     ScAccessibleDocumentPagePreview* mpAccDoc;
441     ScChildGone(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
442     void operator() (const uno::Reference<XAccessible>& xAccessible) const
443     {
444         if (mpAccDoc)
445         {
446 			AccessibleEventObject aEvent;
447 			aEvent.EventId = AccessibleEventId::CHILD;
448 			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
449 			aEvent.OldValue <<= xAccessible;
450 
451 			mpAccDoc->CommitChange(aEvent); // gone child - event
452         }
453     }
454 };
455 
456 struct ScChildNew
457 {
458     ScAccessibleDocumentPagePreview* mpAccDoc;
459     ScChildNew(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
460     void operator() (const uno::Reference<XAccessible>& xAccessible) const
461     {
462         if (mpAccDoc)
463         {
464 			AccessibleEventObject aEvent;
465 			aEvent.EventId = AccessibleEventId::CHILD;
466 			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
467 			aEvent.NewValue <<= xAccessible;
468 
469 			mpAccDoc->CommitChange(aEvent); // new child - event
470         }
471     }
472 };
473 
474 void ScNotesChilds::DataChanged(const Rectangle& rVisRect)
475 {
476     if (mpViewShell && mpAccDoc)
477     {
478         ScXAccList aNewParas;
479         ScXAccList aOldParas;
480         ScAccNotes aNewMarks;
481         mnParagraphs = CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_True, maMarks, aNewMarks, aOldParas, aNewParas);
482         maMarks = aNewMarks;
483         ScAccNotes aNewNotes;
484         mnParagraphs += CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_False, maNotes, aNewNotes, aOldParas, aNewParas);
485         maNotes = aNewNotes;
486 
487         std::for_each(aOldParas.begin(), aOldParas.end(), ScChildGone(mpAccDoc));
488         std::for_each(aNewParas.begin(), aNewParas.end(), ScChildNew(mpAccDoc));
489     }
490 }
491 
492 struct ScChangeOffset
493 {
494     sal_Int32 mnDiff;
495     ScChangeOffset(sal_Int32 nDiff) : mnDiff(nDiff) {}
496     void operator() (const ScAccNote& rNote)
497     {
498         if (rNote.mpTextHelper)
499             rNote.mpTextHelper->SetStartIndex(rNote.mpTextHelper->GetStartIndex() + mnDiff);
500     }
501 };
502 
503 void ScNotesChilds::SetOffset(sal_Int32 nNewOffset)
504 {
505     sal_Int32 nDiff(nNewOffset - mnOffset);
506     if (nDiff != 0)
507     {
508         std::for_each(maMarks.begin(), maMarks.end(), ScChangeOffset(nDiff));
509         std::for_each(maNotes.begin(), maNotes.end(), ScChangeOffset(nDiff));
510         mnOffset = nNewOffset;
511     }
512 }
513 
514 inline ScDocument* ScNotesChilds::GetDocument() const
515 {
516     ScDocument* pDoc = NULL;
517     if (mpViewShell)
518         pDoc = mpViewShell->GetDocument();
519     return pDoc;
520 }
521 
522 class ScIAccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder
523 {
524 public:
525     ScIAccessibleViewForwarder();
526     ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
527                                 ScAccessibleDocumentPagePreview* pAccDoc,
528                                 const MapMode& aMapMode);
529     ~ScIAccessibleViewForwarder();
530 
531 	///=====  IAccessibleViewForwarder  ========================================
532 
533 	virtual sal_Bool IsValid (void) const;
534     virtual Rectangle GetVisibleArea() const;
535     virtual Point LogicToPixel (const Point& rPoint) const;
536     virtual Size LogicToPixel (const Size& rSize) const;
537     virtual Point PixelToLogic (const Point& rPoint) const;
538     virtual Size PixelToLogic (const Size& rSize) const;
539 
540 private:
541     ScPreviewShell*                     mpViewShell;
542     ScAccessibleDocumentPagePreview*    mpAccDoc;
543     MapMode                             maMapMode;
544     sal_Bool                            mbValid;
545 };
546 
547 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
548     : mbValid(sal_False)
549 {
550 }
551 
552 ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
553                                 ScAccessibleDocumentPagePreview* pAccDoc,
554                                 const MapMode& aMapMode)
555     : mpViewShell(pViewShell),
556     mpAccDoc(pAccDoc),
557     maMapMode(aMapMode),
558     mbValid(sal_True)
559 {
560 }
561 
562 ScIAccessibleViewForwarder::~ScIAccessibleViewForwarder()
563 {
564 }
565 
566 ///=====  IAccessibleViewForwarder  ========================================
567 
568 sal_Bool ScIAccessibleViewForwarder::IsValid (void) const
569 {
570     ScUnoGuard aGuard;
571     return mbValid;
572 }
573 
574 Rectangle ScIAccessibleViewForwarder::GetVisibleArea() const
575 {
576     ScUnoGuard aGuard;
577     Rectangle aVisRect;
578     Window* pWin = mpViewShell->GetWindow();
579     if (pWin)
580     {
581         aVisRect.SetSize(pWin->GetOutputSizePixel());
582         aVisRect.SetPos(Point(0, 0));
583 
584         aVisRect = pWin->PixelToLogic(aVisRect, maMapMode);
585     }
586 
587     return aVisRect;
588 }
589 
590 Point ScIAccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
591 {
592     ScUnoGuard aGuard;
593     Point aPoint;
594     Window* pWin = mpViewShell->GetWindow();
595     if (pWin && mpAccDoc)
596     {
597     	Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
598         aPoint = pWin->LogicToPixel(rPoint, maMapMode) + aRect.TopLeft();
599     }
600 
601     return aPoint;
602 }
603 
604 Size ScIAccessibleViewForwarder::LogicToPixel (const Size& rSize) const
605 {
606     ScUnoGuard aGuard;
607     Size aSize;
608     Window* pWin = mpViewShell->GetWindow();
609     if (pWin)
610         aSize = pWin->LogicToPixel(rSize, maMapMode);
611     return aSize;
612 }
613 
614 Point ScIAccessibleViewForwarder::PixelToLogic (const Point& rPoint) const
615 {
616     ScUnoGuard aGuard;
617     Point aPoint;
618     Window* pWin = mpViewShell->GetWindow();
619     if (pWin && mpAccDoc)
620     {
621     	Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
622         aPoint = pWin->PixelToLogic(rPoint - aRect.TopLeft(), maMapMode);
623     }
624     return aPoint;
625 }
626 
627 Size ScIAccessibleViewForwarder::PixelToLogic (const Size& rSize) const
628 {
629     ScUnoGuard aGuard;
630     Size aSize;
631     Window* pWin = mpViewShell->GetWindow();
632     if (pWin)
633         aSize = pWin->PixelToLogic(rSize, maMapMode);
634     return aSize;
635 }
636 
637 struct ScShapeChild
638 {
639     ScShapeChild() : mpAccShape(NULL) {}
640     ScShapeChild(const ScShapeChild& rOld);
641     ~ScShapeChild();
642 	mutable ::accessibility::AccessibleShape* mpAccShape;
643 	com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxShape;
644     sal_Int32 mnRangeId;
645 };
646 
647 ScShapeChild::ScShapeChild(const ScShapeChild& rOld)
648 :
649 mpAccShape(rOld.mpAccShape),
650 mxShape(rOld.mxShape),
651 mnRangeId(rOld.mnRangeId)
652 {
653     if (mpAccShape)
654         mpAccShape->acquire();
655 }
656 
657 ScShapeChild::~ScShapeChild()
658 {
659     if (mpAccShape)
660     {
661         mpAccShape->dispose();
662         mpAccShape->release();
663     }
664 }
665 
666 struct ScShapeChildLess
667 {
668     sal_Bool operator()(const ScShapeChild& rChild1, const ScShapeChild& rChild2) const
669     {
670       sal_Bool bResult(sal_False);
671       if (rChild1.mxShape.is() && rChild2.mxShape.is())
672 	      bResult = (rChild1.mxShape.get() < rChild2.mxShape.get());
673       return bResult;
674     }
675 };
676 
677 typedef std::vector<ScShapeChild> ScShapeChildVec;
678 
679 struct ScShapeRange
680 {
681     ScShapeChildVec maBackShapes;
682     ScShapeChildVec maForeShapes; // inclusive internal shapes
683     ScShapeChildVec maControls;
684     Rectangle       maPixelRect;
685     MapMode         maMapMode;
686     ScIAccessibleViewForwarder maViewForwarder;
687 };
688 
689 typedef std::vector<ScShapeRange> ScShapeRangeVec;
690 
691 class ScShapeChilds : public SfxListener,
692         public ::accessibility::IAccessibleParent
693 {
694 public:
695     ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
696     ~ScShapeChilds();
697 
698     ///=====  SfxListener  =====================================================
699 
700 	virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
701 
702     ///=====  IAccessibleParent  ==============================================
703 
704     virtual sal_Bool ReplaceChild (
705         ::accessibility::AccessibleShape* pCurrentChild,
706 		const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
707 		const long _nIndex,
708 		const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
709 	)	throw (::com::sun::star::uno::RuntimeException);
710 
711     ///=====  Internal  ========================================================
712 
713     void Init();
714 
715     sal_Int32 GetBackShapeCount() const;
716     uno::Reference<XAccessible> GetBackShape(sal_Int32 nIndex) const;
717     sal_Int32 GetForeShapeCount() const;
718     uno::Reference<XAccessible> GetForeShape(sal_Int32 nIndex) const;
719     sal_Int32 GetControlCount() const;
720     uno::Reference<XAccessible> GetControl(sal_Int32 nIndex) const;
721     uno::Reference<XAccessible> GetForegroundShapeAt(const awt::Point& rPoint) const; // inclusive controls
722     uno::Reference<XAccessible> GetBackgroundShapeAt(const awt::Point& rPoint) const;
723 
724     void DataChanged();
725     void VisAreaChanged() const;
726 
727     void SetDrawBroadcaster();
728 private:
729     ScAccessibleDocumentPagePreview* mpAccDoc;
730     ScPreviewShell* mpViewShell;
731     ScShapeRangeVec maShapeRanges;
732 
733     void FindChanged(ScShapeChildVec& aOld, ScShapeChildVec& aNew) const;
734     void FindChanged(ScShapeRange& aOld, ScShapeRange& aNew) const;
735     ::accessibility::AccessibleShape* GetAccShape(const ScShapeChild& rShape) const;
736     ::accessibility::AccessibleShape* GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const;
737     void FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId);
738 //UNUSED2008-05  sal_Bool FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const;
739 
740 //    void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
741 //    void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
742     SdrPage* GetDrawPage() const;
743 };
744 
745 ScShapeChilds::ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
746     :
747     mpAccDoc(pAccDoc),
748     mpViewShell(pViewShell),
749     maShapeRanges(SC_PREVIEW_MAXRANGES)
750 {
751     if (pViewShell)
752     {
753 	    SfxBroadcaster* pDrawBC = pViewShell->GetDocument()->GetDrawBroadcaster();
754 	    if (pDrawBC)
755 		    StartListening(*pDrawBC);
756     }
757 }
758 
759 ScShapeChilds::~ScShapeChilds()
760 {
761     if (mpViewShell)
762     {
763 	    SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
764 	    if (pDrawBC)
765 		    EndListening(*pDrawBC);
766     }
767 }
768 
769 void ScShapeChilds::SetDrawBroadcaster()
770 {
771     if (mpViewShell)
772     {
773 	    SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
774 	    if (pDrawBC)
775 		    StartListening(*pDrawBC, sal_True);
776     }
777 }
778 
779 void ScShapeChilds::Notify(SfxBroadcaster&, const SfxHint& rHint)
780 {
781 	if ( rHint.ISA( SdrHint ) )
782 	{
783 		const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
784         if (pSdrHint)
785         {
786             SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
787             if (pObj && (pObj->GetPage() == GetDrawPage()))
788             {
789                 switch (pSdrHint->GetKind())
790                 {
791                     case HINT_OBJCHG :         // Objekt geaendert
792                     {
793                     }
794                     break;
795                     // no longer necessary
796 /*                    case HINT_OBJINSERTED :    // Neues Zeichenobjekt eingefuegt
797                     {
798                         uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
799                         if (xShape.is())
800                             AddShape(xShape, pObj->GetLayer());
801                     }
802                     break;
803                     case HINT_OBJREMOVED :     // Zeichenobjekt aus Liste entfernt
804                     {
805                         uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
806                         if (xShape.is())
807                             RemoveShape(xShape, pObj->GetLayer());
808                     }
809                     break;*/
810                     default :
811                     {
812                         // other events are not interesting
813                     }
814                     break;
815                 }
816             }
817         }
818     }
819 }
820 
821 void ScShapeChilds::FindChanged(ScShapeChildVec& rOld, ScShapeChildVec& rNew) const
822 {
823     ScShapeChildVec::iterator aOldItr = rOld.begin();
824     ScShapeChildVec::iterator aOldEnd = rOld.end();
825     ScShapeChildVec::const_iterator aNewItr = rNew.begin();
826     ScShapeChildVec::const_iterator aNewEnd = rNew.begin();
827     uno::Reference<XAccessible> xAcc;
828     while ((aNewItr != aNewEnd) && (aOldItr != aOldEnd))
829     {
830         if (aNewItr->mxShape.get() == aOldItr->mxShape.get())
831         {
832             ++aOldItr;
833             ++aNewItr;
834         }
835         else if (aNewItr->mxShape.get() < aOldItr->mxShape.get())
836         {
837             xAcc = GetAccShape(*aNewItr);
838             AccessibleEventObject aEvent;
839             aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
840             aEvent.EventId = AccessibleEventId::CHILD;
841             aEvent.NewValue <<= xAcc;
842             mpAccDoc->CommitChange(aEvent);
843             ++aNewItr;
844         }
845         else
846         {
847             xAcc = GetAccShape(*aOldItr);
848             AccessibleEventObject aEvent;
849             aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
850             aEvent.EventId = AccessibleEventId::CHILD;
851             aEvent.OldValue <<= xAcc;
852             mpAccDoc->CommitChange(aEvent);
853             ++aOldItr;
854         }
855     }
856     while (aOldItr != aOldEnd)
857     {
858         xAcc = GetAccShape(*aOldItr);
859         AccessibleEventObject aEvent;
860         aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
861         aEvent.EventId = AccessibleEventId::CHILD;
862         aEvent.OldValue <<= xAcc;
863         mpAccDoc->CommitChange(aEvent);
864         ++aOldItr;
865     }
866     while (aNewItr != aNewEnd)
867     {
868         xAcc = GetAccShape(*aNewItr);
869         AccessibleEventObject aEvent;
870         aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
871         aEvent.EventId = AccessibleEventId::CHILD;
872         aEvent.NewValue <<= xAcc;
873         mpAccDoc->CommitChange(aEvent);
874         ++aNewItr;
875     }
876 }
877 
878 void ScShapeChilds::FindChanged(ScShapeRange& rOld, ScShapeRange& rNew) const
879 {
880     FindChanged(rOld.maBackShapes, rNew.maBackShapes);
881     FindChanged(rOld.maForeShapes, rNew.maForeShapes);
882     FindChanged(rOld.maControls, rNew.maControls);
883 }
884 
885 void ScShapeChilds::DataChanged()
886 {
887     ScShapeRangeVec aOldShapeRanges(maShapeRanges);
888     maShapeRanges.clear();
889     maShapeRanges.resize(SC_PREVIEW_MAXRANGES);
890     Init();
891     for (sal_Int32 i = 0; i < SC_PREVIEW_MAXRANGES; ++i)
892     {
893         FindChanged(aOldShapeRanges[i], maShapeRanges[i]);
894     }
895 }
896 
897 struct ScVisAreaChanged
898 {
899     const ScIAccessibleViewForwarder* mpViewForwarder;
900     ScVisAreaChanged(const ScIAccessibleViewForwarder* pViewForwarder) : mpViewForwarder(pViewForwarder) {}
901 	void operator() (const ScShapeChild& rAccShapeData) const
902     {
903 	    if (rAccShapeData.mpAccShape)
904         {
905             rAccShapeData.mpAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpViewForwarder);
906         }
907     }
908 };
909 
910 void ScShapeChilds::VisAreaChanged() const
911 {
912     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
913     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
914     while (aItr != aEndItr)
915     {
916         ScVisAreaChanged aVisAreaChanged(&(aItr->maViewForwarder));
917         std::for_each(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), aVisAreaChanged);
918         std::for_each(aItr->maControls.begin(), aItr->maControls.end(), aVisAreaChanged);
919         std::for_each(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), aVisAreaChanged);
920         ++aItr;
921     }
922 }
923 
924     ///=====  IAccessibleParent  ==============================================
925 
926 sal_Bool ScShapeChilds::ReplaceChild (::accessibility::AccessibleShape* /* pCurrentChild */,
927     const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& /* _rxShape */,
928         const long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo& /* _rShapeTreeInfo */)
929         throw (uno::RuntimeException)
930 {
931     DBG_ERRORFILE("should not be called in the page preview");
932     return sal_False;
933 }
934 
935     ///=====  Internal  ========================================================
936 
937 void ScShapeChilds::Init()
938 {
939     if(mpViewShell)
940     {
941         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
942         MapMode aMapMode;
943         Rectangle aPixelPaintRect;
944         sal_uInt8 nRangeId;
945         sal_uInt16 nCount(rData.GetDrawRanges());
946         for (sal_uInt16 i = 0; i < nCount; ++i)
947         {
948             rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId);
949             FillShapes(aPixelPaintRect, aMapMode, nRangeId);
950         }
951     }
952 }
953 
954 sal_Int32 ScShapeChilds::GetBackShapeCount() const
955 {
956     sal_Int32 nCount(0);
957     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
958     for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
959         nCount += aItr->maBackShapes.size();
960     return nCount;
961 }
962 
963 uno::Reference<XAccessible> ScShapeChilds::GetBackShape(sal_Int32 nIndex) const
964 {
965     uno::Reference<XAccessible> xAccessible;
966     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
967     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
968     while ((aItr != aEndItr) && !xAccessible.is())
969     {
970         sal_Int32 nCount(aItr->maBackShapes.size());
971         if(nIndex < nCount)
972             xAccessible = GetAccShape(aItr->maBackShapes, nIndex);
973         else
974             ++aItr;
975         nIndex -= nCount;
976     }
977 
978     if (nIndex >= 0)
979         throw lang::IndexOutOfBoundsException();
980 
981    return xAccessible;
982 }
983 
984 sal_Int32 ScShapeChilds::GetForeShapeCount() const
985 {
986     sal_Int32 nCount(0);
987     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
988     for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
989         nCount += aItr->maForeShapes.size();
990     return nCount;
991 }
992 
993 uno::Reference<XAccessible> ScShapeChilds::GetForeShape(sal_Int32 nIndex) const
994 {
995     uno::Reference<XAccessible> xAccessible;
996     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
997     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
998     while ((aItr != aEndItr) && !xAccessible.is())
999     {
1000         sal_Int32 nCount(aItr->maForeShapes.size());
1001         if(nIndex < nCount)
1002             xAccessible = GetAccShape(aItr->maForeShapes, nIndex);
1003         else
1004             ++aItr;
1005         nIndex -= nCount;
1006     }
1007 
1008     if (nIndex >= 0)
1009         throw lang::IndexOutOfBoundsException();
1010 
1011    return xAccessible;
1012 }
1013 
1014 sal_Int32 ScShapeChilds::GetControlCount() const
1015 {
1016     sal_Int32 nCount(0);
1017     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1018     for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
1019         nCount += aItr->maControls.size();
1020     return nCount;
1021 }
1022 
1023 uno::Reference<XAccessible> ScShapeChilds::GetControl(sal_Int32 nIndex) const
1024 {
1025     uno::Reference<XAccessible> xAccessible;
1026     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1027     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
1028     while ((aItr != aEndItr) && !xAccessible.is())
1029     {
1030         sal_Int32 nCount(aItr->maControls.size());
1031         if(nIndex < nCount)
1032             xAccessible = GetAccShape(aItr->maControls, nIndex);
1033         else
1034             ++aItr;
1035         nIndex -= nCount;
1036     }
1037 
1038     if (nIndex >= 0)
1039         throw lang::IndexOutOfBoundsException();
1040 
1041    return xAccessible;
1042 }
1043 
1044 struct ScShapePointFound
1045 {
1046     Point maPoint;
1047     ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {}
1048     sal_Bool operator() (const ScShapeChild& rShape)
1049     {
1050         sal_Bool bResult(sal_False);
1051         if ((VCLRectangle(rShape.mpAccShape->getBounds())).IsInside(maPoint))
1052             bResult = sal_True;
1053         return bResult;
1054     }
1055 };
1056 
1057 uno::Reference<XAccessible> ScShapeChilds::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls
1058 {
1059     uno::Reference<XAccessible> xAcc;
1060 
1061     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
1062     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1063     while((aItr != aEndItr) && !xAcc.is())
1064     {
1065         ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), ScShapePointFound(rPoint));
1066         if (aFindItr != aItr->maForeShapes.end())
1067             xAcc = GetAccShape(*aFindItr);
1068         else
1069         {
1070             ScShapeChildVec::const_iterator aCtrlItr = std::find_if(aItr->maControls.begin(), aItr->maControls.end(), ScShapePointFound(rPoint));
1071             if (aCtrlItr != aItr->maControls.end())
1072                 xAcc = GetAccShape(*aCtrlItr);
1073             else
1074                 ++aItr;
1075         }
1076     }
1077 
1078     return xAcc;
1079 }
1080 
1081 uno::Reference<XAccessible> ScShapeChilds::GetBackgroundShapeAt(const awt::Point& rPoint) const
1082 {
1083     uno::Reference<XAccessible> xAcc;
1084 
1085     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
1086     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1087     while((aItr != aEndItr) && !xAcc.is())
1088     {
1089         ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), ScShapePointFound(rPoint));
1090         if (aFindItr != aItr->maBackShapes.end())
1091             xAcc = GetAccShape(*aFindItr);
1092         else
1093             ++aItr;
1094     }
1095 
1096     return xAcc;
1097 }
1098 
1099 ::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChild& rShape) const
1100 {
1101 	if (!rShape.mpAccShape)
1102 	{
1103 		::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
1104         ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc, const_cast<ScShapeChilds*>(this));
1105 
1106         if (mpViewShell)
1107         {
1108             ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo;
1109             aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView());
1110             aShapeTreeInfo.SetController(NULL);
1111             aShapeTreeInfo.SetWindow(mpViewShell->GetWindow());
1112             aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder));
1113 		    rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo);
1114 		    if (rShape.mpAccShape)
1115             {
1116 			    rShape.mpAccShape->acquire();
1117                 rShape.mpAccShape->Init();
1118             }
1119         }
1120 	}
1121     return rShape.mpAccShape;
1122 }
1123 
1124 ::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const
1125 {
1126 	return (GetAccShape(rShapes[nIndex]));
1127 }
1128 
1129 void ScShapeChilds::FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId)
1130 {
1131     DBG_ASSERT(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects");
1132     SdrPage* pPage = GetDrawPage();
1133     Window* pWin = mpViewShell->GetWindow();
1134     if (pPage && pWin)
1135     {
1136         sal_Bool bForeAdded(sal_False);
1137         sal_Bool bBackAdded(sal_False);
1138         sal_Bool bControlAdded(sal_False);
1139         Rectangle aClippedPixelPaintRect(aPixelPaintRect);
1140         if (mpAccDoc)
1141         {
1142             Rectangle aRect2(Point(0,0), mpAccDoc->GetBoundingBoxOnScreen().GetSize());
1143             aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2);
1144         }
1145         maShapeRanges[nRangeId].maPixelRect = aClippedPixelPaintRect;
1146         maShapeRanges[nRangeId].maMapMode = aMapMode;
1147         ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode);
1148         maShapeRanges[nRangeId].maViewForwarder = aViewForwarder;
1149         sal_uInt32 nCount(pPage->GetObjCount());
1150         for (sal_uInt32 i = 0; i < nCount; ++i)
1151         {
1152             SdrObject* pObj = pPage->GetObj(i);
1153             if (pObj)
1154             {
1155                 uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1156                 if (xShape.is())
1157                 {
1158                     Rectangle aRect(pWin->LogicToPixel(VCLPoint(xShape->getPosition()), aMapMode), pWin->LogicToPixel(VCLSize(xShape->getSize()), aMapMode));
1159                     if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty())
1160                     {
1161                         ScShapeChild aShape;
1162                         aShape.mxShape = xShape;
1163                         aShape.mnRangeId = nRangeId;
1164                         switch (pObj->GetLayer())
1165                         {
1166                             case SC_LAYER_INTERN:
1167                             case SC_LAYER_FRONT:
1168                             {
1169                                 maShapeRanges[nRangeId].maForeShapes.push_back(aShape);
1170                                 bForeAdded = sal_True;
1171                             }
1172                             break;
1173                             case SC_LAYER_BACK:
1174                             {
1175                                 maShapeRanges[nRangeId].maBackShapes.push_back(aShape);
1176                                 bBackAdded = sal_True;
1177                             }
1178                             break;
1179                             case SC_LAYER_CONTROLS:
1180                             {
1181                                 maShapeRanges[nRangeId].maControls.push_back(aShape);
1182                                 bControlAdded = sal_True;
1183                             }
1184                             break;
1185                             default:
1186                             {
1187                                 DBG_ERRORFILE("I don't know this layer.");
1188                             }
1189                             break;
1190                         }
1191                     }
1192                 }
1193             }
1194         }
1195         if (bForeAdded)
1196             std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess());
1197         if (bBackAdded)
1198             std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess());
1199         if (bControlAdded)
1200             std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess());
1201     }
1202 }
1203 
1204 //UNUSED2008-05  sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const
1205 //UNUSED2008-05  {
1206 //UNUSED2008-05      sal_Bool bResult(sal_False);
1207 //UNUSED2008-05      ScShapeChild aShape;
1208 //UNUSED2008-05      aShape.mxShape = xShape;
1209 //UNUSED2008-05      rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess());
1210 //UNUSED2008-05      if (rItr->mxShape.get() == xShape.get())
1211 //UNUSED2008-05          bResult = sal_True; // if the shape is found
1212 //UNUSED2008-05
1213 //UNUSED2008-05  /*#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
1214 //UNUSED2008-05      ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape);
1215 //UNUSED2008-05      DBG_ASSERT(rItr == aDebugItr, "wrong Shape found");
1216 //UNUSED2008-05  #endif*/
1217 //UNUSED2008-05      return bResult;
1218 //UNUSED2008-05  }
1219 
1220 /*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
1221 {
1222     uno::Reference < XAccessible > xNew;
1223     Window* pWin = mpViewShell->GetWindow();
1224     if (pWin)
1225     {
1226         ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
1227         ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
1228         sal_Bool bNotify(sal_False);
1229         uno::Reference <XAccessible> xAcc;
1230         while (aItr != aEndItr)
1231         {
1232             Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode));
1233             Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize()));
1234             if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty())
1235             {
1236                 ScShapeChild aShape;
1237                 aShape.mxShape = xShape;
1238                 switch (aLayerID)
1239                 {
1240                     case SC_LAYER_INTERN:
1241                     case SC_LAYER_FRONT:
1242                     {
1243                         SetAnchor(aShape);
1244                         aItr->maForeShapes.push_back(aShape);
1245                         std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess());
1246 
1247                     }
1248                     break;
1249                     case SC_LAYER_BACK:
1250                     {
1251                         aItr->maBackShapes.push_back(aShape);
1252                         std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess());
1253                     }
1254                     break;
1255                     case SC_LAYER_CONTROLS:
1256                     {
1257                         SetAnchor(aShape);
1258                         aItr->maControls.push_back(aShape);
1259                         std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess());
1260                     }
1261                     break;
1262                     default:
1263                     {
1264                         DBG_ERRORFILE("I don't know this layer.");
1265                     }
1266                     break;
1267                 }
1268                 if (bNotify)
1269                 {
1270                     xAcc = GetAccShape(aShape);
1271                     AccessibleEventObject aEvent;
1272                     aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
1273                     aEvent.EventId = AccessibleEventId::CHILD;
1274                     aEvent.NewValue <<= xAcc;
1275                     mpAccDoc->CommitChange(aEvent);
1276                     bNotify = sal_False;
1277                 }
1278                 xAcc = NULL;
1279             }
1280             ++aItr;
1281         }
1282     }
1283 }*/
1284 
1285 /*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr)
1286 {
1287     sal_Bool bResult(sal_False);
1288     if (aItr->mpAccShape)
1289     {
1290         bResult = sal_True;
1291         xAcc = aItr->mpAccShape;
1292     }
1293     else
1294         DBG_ERRORFILE("No Accessible object found. Don't know how to notify.");
1295     return bResult;
1296 }*/
1297 
1298 /*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
1299 {
1300     ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
1301     ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
1302     ScShapeChildVec::iterator aEraseItr;
1303     sal_Bool bNotify(sal_False);
1304     uno::Reference <XAccessible> xAcc;
1305     while (aItr != aEndItr)
1306     {
1307         switch (aLayerID)
1308         {
1309             case SC_LAYER_INTERN:
1310             case SC_LAYER_FRONT:
1311             {
1312                 if (FindShape(aItr->maForeShapes, xShape, aEraseItr))
1313                 {
1314                     bNotify = HaveToNotify(xAcc, aEraseItr);
1315                     aItr->maForeShapes.erase(aEraseItr);
1316                 }
1317             }
1318             break;
1319             case SC_LAYER_BACK:
1320             {
1321                 if (FindShape(aItr->maBackShapes, xShape, aEraseItr))
1322                 {
1323                     bNotify = HaveToNotify(xAcc, aEraseItr);
1324                     aItr->maBackShapes.erase(aEraseItr);
1325                 }
1326             }
1327             break;
1328             case SC_LAYER_CONTROLS:
1329             {
1330                 if (FindShape(aItr->maControls, xShape, aEraseItr))
1331                 {
1332                     bNotify = HaveToNotify(xAcc, aEraseItr);
1333                     aItr->maControls.erase(aEraseItr);
1334                 }
1335             }
1336             break;
1337             default:
1338             {
1339                 DBG_ERRORFILE("I don't know this layer.");
1340             }
1341             break;
1342         }
1343         if (bNotify)
1344         {
1345             AccessibleEventObject aEvent;
1346             aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
1347             aEvent.EventId = AccessibleEventId::CHILD;
1348             aEvent.OldValue <<= xAcc;
1349             mpAccDoc->CommitChange(aEvent);
1350             bNotify = sal_False;
1351         }
1352         xAcc = NULL;
1353         ++aItr;
1354     }
1355 }*/
1356 
1357 SdrPage* ScShapeChilds::GetDrawPage() const
1358 {
1359 	SCTAB nTab( mpViewShell->GetLocationData().GetPrintTab() );
1360 	SdrPage* pDrawPage = NULL;
1361 	if (mpViewShell)
1362 	{
1363 		ScDocument* pDoc = mpViewShell->GetDocument();
1364 		if (pDoc && pDoc->GetDrawLayer())
1365 		{
1366 			ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1367 			if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
1368 				pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
1369 		}
1370 	}
1371 	return pDrawPage;
1372 }
1373 
1374 struct ScPagePreviewCountData
1375 {
1376 	//	order is background shapes, header, table or notes, footer, foreground shapes, controls
1377 
1378     Rectangle aVisRect;
1379 	long nBackShapes;
1380 	long nHeaders;
1381 	long nTables;
1382     long nNoteParagraphs;
1383 	long nFooters;
1384 	long nForeShapes;
1385 	long nControls;
1386 
1387 	ScPagePreviewCountData( const ScPreviewLocationData& rData, Window* pSizeWindow,
1388         ScNotesChilds* pNotesChilds, ScShapeChilds* pShapeChilds );
1389 
1390 	long GetTotal() const
1391 	{
1392 		return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls;
1393 	}
1394 };
1395 
1396 ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData,
1397                                 Window* pSizeWindow, ScNotesChilds* pNotesChilds,
1398                                 ScShapeChilds* pShapeChilds) :
1399 	nBackShapes( 0 ),
1400 	nHeaders( 0 ),
1401 	nTables( 0 ),
1402     nNoteParagraphs( 0 ),
1403 	nFooters( 0 ),
1404 	nForeShapes( 0 ),
1405 	nControls( 0 )
1406 {
1407 	Size aOutputSize;
1408 	if ( pSizeWindow )
1409 		aOutputSize = pSizeWindow->GetOutputSizePixel();
1410     Point aPoint;
1411 	aVisRect = Rectangle( aPoint, aOutputSize );
1412 
1413 	Rectangle aObjRect;
1414 
1415 	if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
1416 		nHeaders = 1;
1417 
1418 	if ( rData.GetFooterPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
1419 		nFooters = 1;
1420 
1421 	if ( rData.HasCellsInRange( aVisRect ) )
1422 		nTables = 1;
1423 
1424 	//!	shapes...
1425     nBackShapes = pShapeChilds->GetBackShapeCount();
1426     nForeShapes = pShapeChilds->GetForeShapeCount();
1427     nControls = pShapeChilds->GetControlCount();
1428 
1429     // there are only notes if there is no table
1430     if (nTables == 0)
1431         nNoteParagraphs = pNotesChilds->GetChildsCount();
1432 }
1433 
1434 //=====  internal  ========================================================
1435 
1436 ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
1437         const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) :
1438 	ScAccessibleDocumentBase(rxParent),
1439 	mpViewShell(pViewShell),
1440 	mpNotesChilds(NULL),
1441     mpShapeChilds(NULL),
1442     mpTable(NULL),
1443     mpHeader(NULL),
1444     mpFooter(NULL)
1445 {
1446 	if (pViewShell)
1447 		pViewShell->AddAccessibilityObject(*this);
1448 
1449 //    GetNotesChilds(); not neccessary and reduces the creation performance
1450 //    GetShapeChilds();
1451 }
1452 
1453 ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void)
1454 {
1455 	if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose)
1456 	{
1457 		// increment refcount to prevent double call off dtor
1458 		osl_incrementInterlockedCount( &m_refCount );
1459 		// call dispose to inform object wich have a weak reference to this object
1460 		dispose();
1461 	}
1462 }
1463 
1464 void SAL_CALL ScAccessibleDocumentPagePreview::disposing()
1465 {
1466     ScUnoGuard aGuard;
1467     if (mpTable)
1468     {
1469 	    mpTable->release();
1470         mpTable = NULL;
1471     }
1472     if (mpHeader)
1473     {
1474 	    mpHeader->release();
1475         mpHeader = NULL;
1476     }
1477     if (mpFooter)
1478     {
1479 	    mpFooter->release();
1480         mpFooter = NULL;
1481     }
1482 
1483 	if (mpViewShell)
1484 	{
1485 		mpViewShell->RemoveAccessibilityObject(*this);
1486 		mpViewShell = NULL;
1487 	}
1488 
1489     // #100593# no need to Dispose the AccessibleTextHelper,
1490     // as long as mpNotesChilds are destructed here
1491 	if (mpNotesChilds)
1492 	    DELETEZ(mpNotesChilds);
1493 
1494     if (mpShapeChilds)
1495         DELETEZ(mpShapeChilds);
1496 
1497 	ScAccessibleDocumentBase::disposing();
1498 }
1499 
1500 //=====  SfxListener  =====================================================
1501 
1502 void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1503 {
1504 	if (rHint.ISA( SfxSimpleHint ) )
1505 	{
1506 		const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
1507 		// only notify if child exist, otherwise it is not necessary
1508 		if ((rRef.GetId() == SC_HINT_DATACHANGED))
1509         {
1510             if (mpTable) // if there is no table there is nothing to notify, because no one recongnizes the change
1511             {
1512                 {
1513                     uno::Reference<XAccessible> xAcc = mpTable;
1514                     AccessibleEventObject aEvent;
1515                     aEvent.EventId = AccessibleEventId::CHILD;
1516 					aEvent.Source = uno::Reference< XAccessibleContext >(this);
1517                     aEvent.OldValue <<= xAcc;
1518                     CommitChange(aEvent);
1519                 }
1520 
1521                 mpTable->dispose();
1522                 mpTable->release();
1523                 mpTable = NULL;
1524             }
1525 
1526 	        Size aOutputSize;
1527             Window* pSizeWindow = mpViewShell->GetWindow();
1528 	        if ( pSizeWindow )
1529 		        aOutputSize = pSizeWindow->GetOutputSizePixel();
1530             Point aPoint;
1531 	        Rectangle aVisRect( aPoint, aOutputSize );
1532             GetNotesChilds()->DataChanged(aVisRect);
1533 
1534             GetShapeChilds()->DataChanged();
1535 
1536             const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1537 		    ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1538 
1539             if (aCount.nTables > 0)
1540             {
1541 				//!	order is background shapes, header, table or notes, footer, foreground shapes, controls
1542 				sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1543 
1544 				mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1545                 mpTable->acquire();
1546 				mpTable->Init();
1547 
1548                 {
1549                     uno::Reference<XAccessible> xAcc = mpTable;
1550                     AccessibleEventObject aEvent;
1551                     aEvent.EventId = AccessibleEventId::CHILD;
1552 					aEvent.Source = uno::Reference< XAccessibleContext >(this);
1553                     aEvent.NewValue <<= xAcc;
1554                     CommitChange(aEvent);
1555                 }
1556             }
1557         }
1558         else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
1559         {
1560             GetShapeChilds()->SetDrawBroadcaster();
1561         }
1562         else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
1563         {
1564 	        Size aOutputSize;
1565             Window* pSizeWindow = mpViewShell->GetWindow();
1566 	        if ( pSizeWindow )
1567 		        aOutputSize = pSizeWindow->GetOutputSizePixel();
1568             Point aPoint;
1569 	        Rectangle aVisRect( aPoint, aOutputSize );
1570             GetNotesChilds()->DataChanged(aVisRect);
1571 
1572             GetShapeChilds()->VisAreaChanged();
1573 
1574             AccessibleEventObject aEvent;
1575             aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
1576 			aEvent.Source = uno::Reference< XAccessibleContext >(this);
1577             CommitChange(aEvent);
1578         }
1579     }
1580     else if ( rHint.ISA(ScAccWinFocusLostHint) )
1581     {
1582         CommitFocusLost();
1583     }
1584     else if ( rHint.ISA(ScAccWinFocusGotHint) )
1585     {
1586         CommitFocusGained();
1587     }
1588 	ScAccessibleDocumentBase::Notify(rBC, rHint);
1589 }
1590 
1591 //=====  XAccessibleComponent  ============================================
1592 
1593 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint )
1594 								throw (uno::RuntimeException)
1595 {
1596 	uno::Reference<XAccessible> xAccessible;
1597     if (containsPoint(rPoint))
1598     {
1599 	    ScUnoGuard aGuard;
1600         IsObjectValid();
1601 
1602 	    if ( mpViewShell )
1603 	    {
1604             xAccessible = GetShapeChilds()->GetForegroundShapeAt(rPoint);
1605             if (!xAccessible.is())
1606             {
1607 		        const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1608 		        ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1609 
1610 /*		        if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) )
1611 		        {
1612 			        if ( !mpTable && (aCount.nTables > 0) )
1613 			        {
1614 				        //!	order is background shapes, header, table or notes, footer, foreground shapes, controls
1615 				        sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1616 
1617 				        mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1618                         mpTable->acquire();
1619 				        mpTable->Init();
1620 			        }
1621 			        xAccessible = mpTable;
1622 		        }*/
1623 			    if ( !mpTable && (aCount.nTables > 0) )
1624 			    {
1625 				    //!	order is background shapes, header, table or notes, footer, foreground shapes, controls
1626 				    sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1627 
1628 				    mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1629                     mpTable->acquire();
1630 				    mpTable->Init();
1631 			    }
1632                 if (mpTable && VCLRectangle(mpTable->getBounds()).IsInside(VCLPoint(rPoint)))
1633 			        xAccessible = mpTable;
1634             }
1635             if (!xAccessible.is())
1636                 xAccessible = GetNotesChilds()->GetAt(rPoint);
1637             if (!xAccessible.is())
1638             {
1639 	            if (!mpHeader || !mpFooter)
1640                 {
1641 		            const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1642 		            ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1643 
1644                     if (!mpHeader)
1645                     {
1646                         mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, aCount.nBackShapes + aCount.nHeaders - 1);
1647                         mpHeader->acquire();
1648                     }
1649                     if (!mpFooter)
1650                     {
1651                         mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 );
1652                         mpFooter->acquire();
1653                     }
1654                 }
1655 
1656                 Point aPoint(VCLPoint(rPoint));
1657 
1658                 if (VCLRectangle(mpHeader->getBounds()).IsInside(aPoint))
1659                     xAccessible = mpHeader;
1660                 else if (VCLRectangle(mpFooter->getBounds()).IsInside(aPoint))
1661                     xAccessible = mpFooter;
1662             }
1663             if (!xAccessible.is())
1664                 xAccessible = GetShapeChilds()->GetBackgroundShapeAt(rPoint);
1665 	    }
1666     }
1667 
1668 	return xAccessible;
1669 }
1670 
1671 void SAL_CALL ScAccessibleDocumentPagePreview::grabFocus() throw (uno::RuntimeException)
1672 {
1673 	ScUnoGuard aGuard;
1674     IsObjectValid();
1675 	if (getAccessibleParent().is())
1676 	{
1677 		uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1678 		if (xAccessibleComponent.is())
1679 		{
1680 			// just grab the focus for the window
1681 			xAccessibleComponent->grabFocus();
1682 		}
1683 	}
1684 }
1685 
1686 //=====  XAccessibleContext  ==============================================
1687 
1688 sal_Int32 SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChildCount(void) throw (uno::RuntimeException)
1689 {
1690 	ScUnoGuard aGuard;
1691     IsObjectValid();
1692 
1693 	long nRet = 0;
1694 	if ( mpViewShell )
1695 	{
1696 		ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1697 		nRet = aCount.GetTotal();
1698 	}
1699 
1700 	return nRet;
1701 }
1702 
1703 uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex)
1704 			    throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
1705 {
1706 	ScUnoGuard aGuard;
1707     IsObjectValid();
1708 	uno::Reference<XAccessible> xAccessible;
1709 
1710 	if ( mpViewShell )
1711 	{
1712 		const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1713 		ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1714 
1715 		if ( nIndex < aCount.nBackShapes )
1716 		{
1717 			xAccessible = GetShapeChilds()->GetBackShape(nIndex);
1718 		}
1719 		else if ( nIndex < aCount.nBackShapes + aCount.nHeaders )
1720 		{
1721 			if ( !mpHeader )
1722             {
1723                 mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, nIndex );
1724                 mpHeader->acquire();
1725             }
1726 
1727 			xAccessible = mpHeader;
1728 		}
1729 		else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables )
1730 		{
1731 			if ( !mpTable )
1732             {
1733 				mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1734                 mpTable->acquire();
1735 				mpTable->Init();
1736             }
1737 			xAccessible = mpTable;
1738 		}
1739         else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs )
1740         {
1741             xAccessible = GetNotesChilds()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders);
1742         }
1743 		else if ( (nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters) )
1744 		{
1745 			if ( !mpFooter )
1746             {
1747 				mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, nIndex );
1748                 mpFooter->acquire();
1749             }
1750 			xAccessible = mpFooter;
1751 		}
1752 		else
1753         {
1754             sal_Int32 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters));
1755             if (nIdx < aCount.nForeShapes)
1756                 xAccessible = GetShapeChilds()->GetForeShape(nIdx);
1757             else
1758                 xAccessible = GetShapeChilds()->GetControl(nIdx - aCount.nForeShapes);
1759         }
1760 	}
1761 
1762 	if ( !xAccessible.is() )
1763 		throw lang::IndexOutOfBoundsException();
1764 
1765 	return xAccessible;
1766 }
1767 
1768     ///	Return the set of current states.
1769 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleStateSet(void)
1770 					    throw (uno::RuntimeException)
1771 {
1772 	ScUnoGuard aGuard;
1773 	uno::Reference<XAccessibleStateSet> xParentStates;
1774 	if (getAccessibleParent().is())
1775 	{
1776 		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1777 		xParentStates = xParentContext->getAccessibleStateSet();
1778 	}
1779 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1780 	if (IsDefunc(xParentStates))
1781 		pStateSet->AddState(AccessibleStateType::DEFUNC);
1782     else
1783     {
1784 	    // never editable
1785 	    pStateSet->AddState(AccessibleStateType::ENABLED);
1786 	    pStateSet->AddState(AccessibleStateType::OPAQUE);
1787 	    if (isShowing())
1788 		    pStateSet->AddState(AccessibleStateType::SHOWING);
1789 	    if (isVisible())
1790 		    pStateSet->AddState(AccessibleStateType::VISIBLE);
1791     }
1792 	return pStateSet;
1793 }
1794 
1795 	//=====  XServiceInfo  ====================================================
1796 
1797 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::getImplementationName(void)
1798 				    throw (uno::RuntimeException)
1799 {
1800 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview"));
1801 }
1802 
1803 uno::Sequence< ::rtl::OUString> SAL_CALL ScAccessibleDocumentPagePreview::getSupportedServiceNames(void)
1804 			        throw (uno::RuntimeException)
1805 {
1806 	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
1807     sal_Int32 nOldSize(aSequence.getLength());
1808     aSequence.realloc(nOldSize + 1);
1809     ::rtl::OUString* pNames = aSequence.getArray();
1810 
1811 	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView"));
1812 
1813 	return aSequence;
1814 }
1815 
1816 //=====  XTypeProvider  =======================================================
1817 
1818 uno::Sequence<sal_Int8> SAL_CALL
1819 	ScAccessibleDocumentPagePreview::getImplementationId(void)
1820     throw (uno::RuntimeException)
1821 {
1822     ScUnoGuard aGuard;
1823     IsObjectValid();
1824 	static uno::Sequence<sal_Int8> aId;
1825 	if (aId.getLength() == 0)
1826 	{
1827 		aId.realloc (16);
1828 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
1829 	}
1830 	return aId;
1831 }
1832 
1833 //=====  internal  ========================================================
1834 
1835 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleDescription(void)
1836 				    throw (uno::RuntimeException)
1837 {
1838     rtl::OUString sDescription = String(ScResId(STR_ACC_PREVIEWDOC_DESCR));
1839 	return sDescription;
1840 }
1841 
1842 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleName(void)
1843 				    throw (uno::RuntimeException)
1844 {
1845     rtl::OUString sName = String(ScResId(STR_ACC_PREVIEWDOC_NAME));
1846 	return sName;
1847 }
1848 
1849 Rectangle ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
1850 {
1851 	Rectangle aRect;
1852 	if (mpViewShell)
1853 	{
1854 		Window* pWindow = mpViewShell->GetWindow();
1855 		if (pWindow)
1856 			aRect = pWindow->GetWindowExtentsRelative(NULL);
1857 	}
1858 	return aRect;
1859 }
1860 
1861 Rectangle ScAccessibleDocumentPagePreview::GetBoundingBox() const throw (uno::RuntimeException)
1862 {
1863 	Rectangle aRect;
1864 	if (mpViewShell)
1865 	{
1866 		Window* pWindow = mpViewShell->GetWindow();
1867 		if (pWindow)
1868 			aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
1869 	}
1870 	return aRect;
1871 }
1872 
1873 sal_Bool ScAccessibleDocumentPagePreview::IsDefunc(
1874 	const uno::Reference<XAccessibleStateSet>& rxParentStates)
1875 {
1876 	return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
1877 		(rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
1878 }
1879 
1880 ScNotesChilds* ScAccessibleDocumentPagePreview::GetNotesChilds()
1881 {
1882     if (!mpNotesChilds && mpViewShell)
1883     {
1884         mpNotesChilds = new ScNotesChilds(mpViewShell, this);
1885 
1886 		const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1887 		ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1888 
1889         //!	order is background shapes, header, table or notes, footer, foreground shapes, controls
1890         mpNotesChilds->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders);
1891     }
1892     return mpNotesChilds;
1893 }
1894 
1895 ScShapeChilds* ScAccessibleDocumentPagePreview::GetShapeChilds()
1896 {
1897     if (!mpShapeChilds && mpViewShell)
1898     {
1899         mpShapeChilds = new ScShapeChilds(mpViewShell, this);
1900         mpShapeChilds->Init();
1901     }
1902 
1903     return mpShapeChilds;
1904 }
1905 
1906 //UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable()
1907 //UNUSED2009-05 {
1908 //UNUSED2009-05     if (!mpTable)
1909 //UNUSED2009-05     {
1910 //UNUSED2009-05         if ( mpViewShell )
1911 //UNUSED2009-05         {
1912 //UNUSED2009-05             const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1913 //UNUSED2009-05             ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1914 //UNUSED2009-05             //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1915 //UNUSED2009-05             sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1916 //UNUSED2009-05
1917 //UNUSED2009-05             mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1918 //UNUSED2009-05             mpTable->acquire();
1919 //UNUSED2009-05             mpTable->Init();
1920 //UNUSED2009-05         }
1921 //UNUSED2009-05     }
1922 //UNUSED2009-05     return mpTable;
1923 //UNUSED2009-05 }
1924 
1925 //UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged()
1926 //UNUSED2009-05 {
1927 //UNUSED2009-05     if (mpViewShell)
1928 //UNUSED2009-05     {
1929 //UNUSED2009-05         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1930 //UNUSED2009-05         ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1931 //UNUSED2009-05         //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1932 //UNUSED2009-05         if(mpHeader)
1933 //UNUSED2009-05             mpHeader->SetCurrentIndexInParent(aCount.nBackShapes);
1934 //UNUSED2009-05         if (mpTable)
1935 //UNUSED2009-05             mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders);
1936 //UNUSED2009-05         if (mpFooter)
1937 //UNUSED2009-05             mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs);
1938 //UNUSED2009-05
1939 //UNUSED2009-05         if (mpNotesChilds)
1940 //UNUSED2009-05             mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders);
1941 //UNUSED2009-05     }
1942 //UNUSED2009-05 }
1943