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