xref: /trunk/main/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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     );
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 {
926     DBG_ERRORFILE("should not be called in the page preview");
927     return sal_False;
928 }
929 
930     ///=====  Internal  ========================================================
931 
Init()932 void ScShapeChilds::Init()
933 {
934     if(mpViewShell)
935     {
936         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
937         MapMode aMapMode;
938         Rectangle aPixelPaintRect;
939         sal_uInt8 nRangeId;
940         sal_uInt16 nCount(rData.GetDrawRanges());
941         for (sal_uInt16 i = 0; i < nCount; ++i)
942         {
943             rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId);
944             FillShapes(aPixelPaintRect, aMapMode, nRangeId);
945         }
946     }
947 }
948 
GetBackShapeCount() const949 sal_Int32 ScShapeChilds::GetBackShapeCount() const
950 {
951     sal_Int32 nCount(0);
952     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
953     for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
954         nCount += aItr->maBackShapes.size();
955     return nCount;
956 }
957 
GetBackShape(sal_Int32 nIndex) const958 uno::Reference<XAccessible> ScShapeChilds::GetBackShape(sal_Int32 nIndex) const
959 {
960     uno::Reference<XAccessible> xAccessible;
961     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
962     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
963     while ((aItr != aEndItr) && !xAccessible.is())
964     {
965         sal_Int32 nCount(aItr->maBackShapes.size());
966         if(nIndex < nCount)
967             xAccessible = GetAccShape(aItr->maBackShapes, nIndex);
968         else
969             ++aItr;
970         nIndex -= nCount;
971     }
972 
973     if (nIndex >= 0)
974         throw lang::IndexOutOfBoundsException();
975 
976    return xAccessible;
977 }
978 
GetForeShapeCount() const979 sal_Int32 ScShapeChilds::GetForeShapeCount() const
980 {
981     sal_Int32 nCount(0);
982     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
983     for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
984         nCount += aItr->maForeShapes.size();
985     return nCount;
986 }
987 
GetForeShape(sal_Int32 nIndex) const988 uno::Reference<XAccessible> ScShapeChilds::GetForeShape(sal_Int32 nIndex) const
989 {
990     uno::Reference<XAccessible> xAccessible;
991     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
992     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
993     while ((aItr != aEndItr) && !xAccessible.is())
994     {
995         sal_Int32 nCount(aItr->maForeShapes.size());
996         if(nIndex < nCount)
997             xAccessible = GetAccShape(aItr->maForeShapes, nIndex);
998         else
999             ++aItr;
1000         nIndex -= nCount;
1001     }
1002 
1003     if (nIndex >= 0)
1004         throw lang::IndexOutOfBoundsException();
1005 
1006    return xAccessible;
1007 }
1008 
GetControlCount() const1009 sal_Int32 ScShapeChilds::GetControlCount() const
1010 {
1011     sal_Int32 nCount(0);
1012     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1013     for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
1014         nCount += aItr->maControls.size();
1015     return nCount;
1016 }
1017 
GetControl(sal_Int32 nIndex) const1018 uno::Reference<XAccessible> ScShapeChilds::GetControl(sal_Int32 nIndex) const
1019 {
1020     uno::Reference<XAccessible> xAccessible;
1021     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1022     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
1023     while ((aItr != aEndItr) && !xAccessible.is())
1024     {
1025         sal_Int32 nCount(aItr->maControls.size());
1026         if(nIndex < nCount)
1027             xAccessible = GetAccShape(aItr->maControls, nIndex);
1028         else
1029             ++aItr;
1030         nIndex -= nCount;
1031     }
1032 
1033     if (nIndex >= 0)
1034         throw lang::IndexOutOfBoundsException();
1035 
1036    return xAccessible;
1037 }
1038 
1039 struct ScShapePointFound
1040 {
1041     Point maPoint;
ScShapePointFoundScShapePointFound1042     ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {}
operator ()ScShapePointFound1043     sal_Bool operator() (const ScShapeChild& rShape)
1044     {
1045         sal_Bool bResult(sal_False);
1046         if ((VCLRectangle(rShape.mpAccShape->getBounds())).IsInside(maPoint))
1047             bResult = sal_True;
1048         return bResult;
1049     }
1050 };
1051 
GetForegroundShapeAt(const awt::Point & rPoint) const1052 uno::Reference<XAccessible> ScShapeChilds::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls
1053 {
1054     uno::Reference<XAccessible> xAcc;
1055 
1056     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
1057     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1058     while((aItr != aEndItr) && !xAcc.is())
1059     {
1060         ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), ScShapePointFound(rPoint));
1061         if (aFindItr != aItr->maForeShapes.end())
1062             xAcc = GetAccShape(*aFindItr);
1063         else
1064         {
1065             ScShapeChildVec::const_iterator aCtrlItr = std::find_if(aItr->maControls.begin(), aItr->maControls.end(), ScShapePointFound(rPoint));
1066             if (aCtrlItr != aItr->maControls.end())
1067                 xAcc = GetAccShape(*aCtrlItr);
1068             else
1069                 ++aItr;
1070         }
1071     }
1072 
1073     return xAcc;
1074 }
1075 
GetBackgroundShapeAt(const awt::Point & rPoint) const1076 uno::Reference<XAccessible> ScShapeChilds::GetBackgroundShapeAt(const awt::Point& rPoint) const
1077 {
1078     uno::Reference<XAccessible> xAcc;
1079 
1080     ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
1081     ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
1082     while((aItr != aEndItr) && !xAcc.is())
1083     {
1084         ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), ScShapePointFound(rPoint));
1085         if (aFindItr != aItr->maBackShapes.end())
1086             xAcc = GetAccShape(*aFindItr);
1087         else
1088             ++aItr;
1089     }
1090 
1091     return xAcc;
1092 }
1093 
GetAccShape(const ScShapeChild & rShape) const1094 ::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChild& rShape) const
1095 {
1096     if (!rShape.mpAccShape)
1097     {
1098         ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
1099         ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc, const_cast<ScShapeChilds*>(this));
1100 
1101         if (mpViewShell)
1102         {
1103             ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo;
1104             aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView());
1105             aShapeTreeInfo.SetController(NULL);
1106             aShapeTreeInfo.SetWindow(mpViewShell->GetWindow());
1107             aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder));
1108             rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo);
1109             if (rShape.mpAccShape)
1110             {
1111                 rShape.mpAccShape->acquire();
1112                 rShape.mpAccShape->Init();
1113             }
1114         }
1115     }
1116     return rShape.mpAccShape;
1117 }
1118 
GetAccShape(const ScShapeChildVec & rShapes,sal_Int32 nIndex) const1119 ::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const
1120 {
1121     return (GetAccShape(rShapes[nIndex]));
1122 }
1123 
FillShapes(const Rectangle & aPixelPaintRect,const MapMode & aMapMode,sal_uInt8 nRangeId)1124 void ScShapeChilds::FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId)
1125 {
1126     DBG_ASSERT(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects");
1127     SdrPage* pPage = GetDrawPage();
1128     Window* pWin = mpViewShell->GetWindow();
1129     if (pPage && pWin)
1130     {
1131         sal_Bool bForeAdded(sal_False);
1132         sal_Bool bBackAdded(sal_False);
1133         sal_Bool bControlAdded(sal_False);
1134         Rectangle aClippedPixelPaintRect(aPixelPaintRect);
1135         if (mpAccDoc)
1136         {
1137             Rectangle aRect2(Point(0,0), mpAccDoc->GetBoundingBoxOnScreen().GetSize());
1138             aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2);
1139         }
1140         maShapeRanges[nRangeId].maPixelRect = aClippedPixelPaintRect;
1141         maShapeRanges[nRangeId].maMapMode = aMapMode;
1142         ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode);
1143         maShapeRanges[nRangeId].maViewForwarder = aViewForwarder;
1144         sal_uInt32 nCount(pPage->GetObjCount());
1145         for (sal_uInt32 i = 0; i < nCount; ++i)
1146         {
1147             SdrObject* pObj = pPage->GetObj(i);
1148             if (pObj)
1149             {
1150                 uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1151                 if (xShape.is())
1152                 {
1153                     Rectangle aRect(pWin->LogicToPixel(VCLPoint(xShape->getPosition()), aMapMode), pWin->LogicToPixel(VCLSize(xShape->getSize()), aMapMode));
1154                     if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty())
1155                     {
1156                         ScShapeChild aShape;
1157                         aShape.mxShape = xShape;
1158                         aShape.mnRangeId = nRangeId;
1159                         switch (pObj->GetLayer())
1160                         {
1161                             case SC_LAYER_INTERN:
1162                             case SC_LAYER_FRONT:
1163                             {
1164                                 maShapeRanges[nRangeId].maForeShapes.push_back(aShape);
1165                                 bForeAdded = sal_True;
1166                             }
1167                             break;
1168                             case SC_LAYER_BACK:
1169                             {
1170                                 maShapeRanges[nRangeId].maBackShapes.push_back(aShape);
1171                                 bBackAdded = sal_True;
1172                             }
1173                             break;
1174                             case SC_LAYER_CONTROLS:
1175                             {
1176                                 maShapeRanges[nRangeId].maControls.push_back(aShape);
1177                                 bControlAdded = sal_True;
1178                             }
1179                             break;
1180                             default:
1181                             {
1182                                 DBG_ERRORFILE("I don't know this layer.");
1183                             }
1184                             break;
1185                         }
1186                     }
1187                 }
1188             }
1189         }
1190         if (bForeAdded)
1191             std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess());
1192         if (bBackAdded)
1193             std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess());
1194         if (bControlAdded)
1195             std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess());
1196     }
1197 }
1198 
1199 //UNUSED2008-05  sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const
1200 //UNUSED2008-05  {
1201 //UNUSED2008-05      sal_Bool bResult(sal_False);
1202 //UNUSED2008-05      ScShapeChild aShape;
1203 //UNUSED2008-05      aShape.mxShape = xShape;
1204 //UNUSED2008-05      rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess());
1205 //UNUSED2008-05      if (rItr->mxShape.get() == xShape.get())
1206 //UNUSED2008-05          bResult = sal_True; // if the shape is found
1207 //UNUSED2008-05
1208 //UNUSED2008-05  /*#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
1209 //UNUSED2008-05      ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape);
1210 //UNUSED2008-05      DBG_ASSERT(rItr == aDebugItr, "wrong Shape found");
1211 //UNUSED2008-05  #endif*/
1212 //UNUSED2008-05      return bResult;
1213 //UNUSED2008-05  }
1214 
1215 /*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
1216 {
1217     uno::Reference < XAccessible > xNew;
1218     Window* pWin = mpViewShell->GetWindow();
1219     if (pWin)
1220     {
1221         ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
1222         ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
1223         sal_Bool bNotify(sal_False);
1224         uno::Reference <XAccessible> xAcc;
1225         while (aItr != aEndItr)
1226         {
1227             Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode));
1228             Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize()));
1229             if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty())
1230             {
1231                 ScShapeChild aShape;
1232                 aShape.mxShape = xShape;
1233                 switch (aLayerID)
1234                 {
1235                     case SC_LAYER_INTERN:
1236                     case SC_LAYER_FRONT:
1237                     {
1238                         SetAnchor(aShape);
1239                         aItr->maForeShapes.push_back(aShape);
1240                         std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess());
1241 
1242                     }
1243                     break;
1244                     case SC_LAYER_BACK:
1245                     {
1246                         aItr->maBackShapes.push_back(aShape);
1247                         std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess());
1248                     }
1249                     break;
1250                     case SC_LAYER_CONTROLS:
1251                     {
1252                         SetAnchor(aShape);
1253                         aItr->maControls.push_back(aShape);
1254                         std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess());
1255                     }
1256                     break;
1257                     default:
1258                     {
1259                         DBG_ERRORFILE("I don't know this layer.");
1260                     }
1261                     break;
1262                 }
1263                 if (bNotify)
1264                 {
1265                     xAcc = GetAccShape(aShape);
1266                     AccessibleEventObject aEvent;
1267                     aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
1268                     aEvent.EventId = AccessibleEventId::CHILD;
1269                     aEvent.NewValue <<= xAcc;
1270                     mpAccDoc->CommitChange(aEvent);
1271                     bNotify = sal_False;
1272                 }
1273                 xAcc = NULL;
1274             }
1275             ++aItr;
1276         }
1277     }
1278 }*/
1279 
1280 /*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr)
1281 {
1282     sal_Bool bResult(sal_False);
1283     if (aItr->mpAccShape)
1284     {
1285         bResult = sal_True;
1286         xAcc = aItr->mpAccShape;
1287     }
1288     else
1289         DBG_ERRORFILE("No Accessible object found. Don't know how to notify.");
1290     return bResult;
1291 }*/
1292 
1293 /*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
1294 {
1295     ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
1296     ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
1297     ScShapeChildVec::iterator aEraseItr;
1298     sal_Bool bNotify(sal_False);
1299     uno::Reference <XAccessible> xAcc;
1300     while (aItr != aEndItr)
1301     {
1302         switch (aLayerID)
1303         {
1304             case SC_LAYER_INTERN:
1305             case SC_LAYER_FRONT:
1306             {
1307                 if (FindShape(aItr->maForeShapes, xShape, aEraseItr))
1308                 {
1309                     bNotify = HaveToNotify(xAcc, aEraseItr);
1310                     aItr->maForeShapes.erase(aEraseItr);
1311                 }
1312             }
1313             break;
1314             case SC_LAYER_BACK:
1315             {
1316                 if (FindShape(aItr->maBackShapes, xShape, aEraseItr))
1317                 {
1318                     bNotify = HaveToNotify(xAcc, aEraseItr);
1319                     aItr->maBackShapes.erase(aEraseItr);
1320                 }
1321             }
1322             break;
1323             case SC_LAYER_CONTROLS:
1324             {
1325                 if (FindShape(aItr->maControls, xShape, aEraseItr))
1326                 {
1327                     bNotify = HaveToNotify(xAcc, aEraseItr);
1328                     aItr->maControls.erase(aEraseItr);
1329                 }
1330             }
1331             break;
1332             default:
1333             {
1334                 DBG_ERRORFILE("I don't know this layer.");
1335             }
1336             break;
1337         }
1338         if (bNotify)
1339         {
1340             AccessibleEventObject aEvent;
1341             aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
1342             aEvent.EventId = AccessibleEventId::CHILD;
1343             aEvent.OldValue <<= xAcc;
1344             mpAccDoc->CommitChange(aEvent);
1345             bNotify = sal_False;
1346         }
1347         xAcc = NULL;
1348         ++aItr;
1349     }
1350 }*/
1351 
GetDrawPage() const1352 SdrPage* ScShapeChilds::GetDrawPage() const
1353 {
1354     SCTAB nTab( mpViewShell->GetLocationData().GetPrintTab() );
1355     SdrPage* pDrawPage = NULL;
1356     if (mpViewShell)
1357     {
1358         ScDocument* pDoc = mpViewShell->GetDocument();
1359         if (pDoc && pDoc->GetDrawLayer())
1360         {
1361             ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1362             if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
1363                 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
1364         }
1365     }
1366     return pDrawPage;
1367 }
1368 
1369 struct ScPagePreviewCountData
1370 {
1371     //  order is background shapes, header, table or notes, footer, foreground shapes, controls
1372 
1373     Rectangle aVisRect;
1374     long nBackShapes;
1375     long nHeaders;
1376     long nTables;
1377     long nNoteParagraphs;
1378     long nFooters;
1379     long nForeShapes;
1380     long nControls;
1381 
1382     ScPagePreviewCountData( const ScPreviewLocationData& rData, Window* pSizeWindow,
1383         ScNotesChilds* pNotesChilds, ScShapeChilds* pShapeChilds );
1384 
GetTotalScPagePreviewCountData1385     long GetTotal() const
1386     {
1387         return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls;
1388     }
1389 };
1390 
ScPagePreviewCountData(const ScPreviewLocationData & rData,Window * pSizeWindow,ScNotesChilds * pNotesChilds,ScShapeChilds * pShapeChilds)1391 ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData,
1392                                 Window* pSizeWindow, ScNotesChilds* pNotesChilds,
1393                                 ScShapeChilds* pShapeChilds) :
1394     nBackShapes( 0 ),
1395     nHeaders( 0 ),
1396     nTables( 0 ),
1397     nNoteParagraphs( 0 ),
1398     nFooters( 0 ),
1399     nForeShapes( 0 ),
1400     nControls( 0 )
1401 {
1402     Size aOutputSize;
1403     if ( pSizeWindow )
1404         aOutputSize = pSizeWindow->GetOutputSizePixel();
1405     Point aPoint;
1406     aVisRect = Rectangle( aPoint, aOutputSize );
1407 
1408     Rectangle aObjRect;
1409 
1410     if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
1411         nHeaders = 1;
1412 
1413     if ( rData.GetFooterPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
1414         nFooters = 1;
1415 
1416     if ( rData.HasCellsInRange( aVisRect ) )
1417         nTables = 1;
1418 
1419     //! shapes...
1420     nBackShapes = pShapeChilds->GetBackShapeCount();
1421     nForeShapes = pShapeChilds->GetForeShapeCount();
1422     nControls = pShapeChilds->GetControlCount();
1423 
1424     // there are only notes if there is no table
1425     if (nTables == 0)
1426         nNoteParagraphs = pNotesChilds->GetChildsCount();
1427 }
1428 
1429 //=====  internal  ========================================================
1430 
ScAccessibleDocumentPagePreview(const uno::Reference<XAccessible> & rxParent,ScPreviewShell * pViewShell)1431 ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
1432         const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) :
1433     ScAccessibleDocumentBase(rxParent),
1434     mpViewShell(pViewShell),
1435     mpNotesChilds(NULL),
1436     mpShapeChilds(NULL),
1437     mpTable(NULL),
1438     mpHeader(NULL),
1439     mpFooter(NULL)
1440 {
1441     if (pViewShell)
1442         pViewShell->AddAccessibilityObject(*this);
1443 
1444 //    GetNotesChilds(); not necessary and reduces the creation performance
1445 //    GetShapeChilds();
1446 }
1447 
~ScAccessibleDocumentPagePreview(void)1448 ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void)
1449 {
1450     if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose)
1451     {
1452         // increment refcount to prevent double call off dtor
1453         osl_incrementInterlockedCount( &m_refCount );
1454         // call dispose to inform object which have a weak reference to this object
1455         dispose();
1456     }
1457 }
1458 
disposing()1459 void SAL_CALL ScAccessibleDocumentPagePreview::disposing()
1460 {
1461     ScUnoGuard aGuard;
1462     if (mpTable)
1463     {
1464         mpTable->release();
1465         mpTable = NULL;
1466     }
1467     if (mpHeader)
1468     {
1469         mpHeader->release();
1470         mpHeader = NULL;
1471     }
1472     if (mpFooter)
1473     {
1474         mpFooter->release();
1475         mpFooter = NULL;
1476     }
1477 
1478     if (mpViewShell)
1479     {
1480         mpViewShell->RemoveAccessibilityObject(*this);
1481         mpViewShell = NULL;
1482     }
1483 
1484     // #100593# no need to Dispose the AccessibleTextHelper,
1485     // as long as mpNotesChilds are destructed here
1486     if (mpNotesChilds)
1487         DELETEZ(mpNotesChilds);
1488 
1489     if (mpShapeChilds)
1490         DELETEZ(mpShapeChilds);
1491 
1492     ScAccessibleDocumentBase::disposing();
1493 }
1494 
1495 //=====  SfxListener  =====================================================
1496 
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)1497 void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1498 {
1499     if (rHint.ISA( SfxSimpleHint ) )
1500     {
1501         const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
1502         // only notify if child exist, otherwise it is not necessary
1503         if ((rRef.GetId() == SC_HINT_DATACHANGED))
1504         {
1505             if (mpTable) // if there is no table there is nothing to notify, because no one recongnizes the change
1506             {
1507                 {
1508                     uno::Reference<XAccessible> xAcc = mpTable;
1509                     AccessibleEventObject aEvent;
1510                     aEvent.EventId = AccessibleEventId::CHILD;
1511                     aEvent.Source = uno::Reference< XAccessibleContext >(this);
1512                     aEvent.OldValue <<= xAcc;
1513                     CommitChange(aEvent);
1514                 }
1515 
1516                 mpTable->dispose();
1517                 mpTable->release();
1518                 mpTable = NULL;
1519             }
1520 
1521             Size aOutputSize;
1522             Window* pSizeWindow = mpViewShell->GetWindow();
1523             if ( pSizeWindow )
1524                 aOutputSize = pSizeWindow->GetOutputSizePixel();
1525             Point aPoint;
1526             Rectangle aVisRect( aPoint, aOutputSize );
1527             GetNotesChilds()->DataChanged(aVisRect);
1528 
1529             GetShapeChilds()->DataChanged();
1530 
1531             const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1532             ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1533 
1534             if (aCount.nTables > 0)
1535             {
1536                 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1537                 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1538 
1539                 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1540                 mpTable->acquire();
1541                 mpTable->Init();
1542 
1543                 {
1544                     uno::Reference<XAccessible> xAcc = mpTable;
1545                     AccessibleEventObject aEvent;
1546                     aEvent.EventId = AccessibleEventId::CHILD;
1547                     aEvent.Source = uno::Reference< XAccessibleContext >(this);
1548                     aEvent.NewValue <<= xAcc;
1549                     CommitChange(aEvent);
1550                 }
1551             }
1552         }
1553         else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
1554         {
1555             GetShapeChilds()->SetDrawBroadcaster();
1556         }
1557         else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
1558         {
1559             Size aOutputSize;
1560             Window* pSizeWindow = mpViewShell->GetWindow();
1561             if ( pSizeWindow )
1562                 aOutputSize = pSizeWindow->GetOutputSizePixel();
1563             Point aPoint;
1564             Rectangle aVisRect( aPoint, aOutputSize );
1565             GetNotesChilds()->DataChanged(aVisRect);
1566 
1567             GetShapeChilds()->VisAreaChanged();
1568 
1569             AccessibleEventObject aEvent;
1570             aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
1571             aEvent.Source = uno::Reference< XAccessibleContext >(this);
1572             CommitChange(aEvent);
1573         }
1574     }
1575     else if ( rHint.ISA(ScAccWinFocusLostHint) )
1576     {
1577         CommitFocusLost();
1578     }
1579     else if ( rHint.ISA(ScAccWinFocusGotHint) )
1580     {
1581         CommitFocusGained();
1582     }
1583     ScAccessibleDocumentBase::Notify(rBC, rHint);
1584 }
1585 
1586 //=====  XAccessibleComponent  ============================================
1587 
getAccessibleAtPoint(const awt::Point & rPoint)1588 uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint )
1589 {
1590     uno::Reference<XAccessible> xAccessible;
1591     if (containsPoint(rPoint))
1592     {
1593         ScUnoGuard aGuard;
1594         IsObjectValid();
1595 
1596         if ( mpViewShell )
1597         {
1598             xAccessible = GetShapeChilds()->GetForegroundShapeAt(rPoint);
1599             if (!xAccessible.is())
1600             {
1601                 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1602                 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1603 
1604 /*              if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) )
1605                 {
1606                     if ( !mpTable && (aCount.nTables > 0) )
1607                     {
1608                         //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1609                         sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1610 
1611                         mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1612                         mpTable->acquire();
1613                         mpTable->Init();
1614                     }
1615                     xAccessible = mpTable;
1616                 }*/
1617                 if ( !mpTable && (aCount.nTables > 0) )
1618                 {
1619                     //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1620                     sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1621 
1622                     mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1623                     mpTable->acquire();
1624                     mpTable->Init();
1625                 }
1626                 if (mpTable && VCLRectangle(mpTable->getBounds()).IsInside(VCLPoint(rPoint)))
1627                     xAccessible = mpTable;
1628             }
1629             if (!xAccessible.is())
1630                 xAccessible = GetNotesChilds()->GetAt(rPoint);
1631             if (!xAccessible.is())
1632             {
1633                 if (!mpHeader || !mpFooter)
1634                 {
1635                     const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1636                     ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1637 
1638                     if (!mpHeader)
1639                     {
1640                         mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, aCount.nBackShapes + aCount.nHeaders - 1);
1641                         mpHeader->acquire();
1642                     }
1643                     if (!mpFooter)
1644                     {
1645                         mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 );
1646                         mpFooter->acquire();
1647                     }
1648                 }
1649 
1650                 Point aPoint(VCLPoint(rPoint));
1651 
1652                 if (VCLRectangle(mpHeader->getBounds()).IsInside(aPoint))
1653                     xAccessible = mpHeader;
1654                 else if (VCLRectangle(mpFooter->getBounds()).IsInside(aPoint))
1655                     xAccessible = mpFooter;
1656             }
1657             if (!xAccessible.is())
1658                 xAccessible = GetShapeChilds()->GetBackgroundShapeAt(rPoint);
1659         }
1660     }
1661 
1662     return xAccessible;
1663 }
1664 
grabFocus()1665 void SAL_CALL ScAccessibleDocumentPagePreview::grabFocus()
1666 {
1667     ScUnoGuard aGuard;
1668     IsObjectValid();
1669     if (getAccessibleParent().is())
1670     {
1671         uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1672         if (xAccessibleComponent.is())
1673         {
1674             // just grab the focus for the window
1675             xAccessibleComponent->grabFocus();
1676         }
1677     }
1678 }
1679 
1680 //=====  XAccessibleContext  ==============================================
1681 
getAccessibleChildCount(void)1682 sal_Int32 SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChildCount(void)
1683 {
1684     ScUnoGuard aGuard;
1685     IsObjectValid();
1686 
1687     long nRet = 0;
1688     if ( mpViewShell )
1689     {
1690         ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1691         nRet = aCount.GetTotal();
1692     }
1693 
1694     return nRet;
1695 }
1696 
getAccessibleChild(sal_Int32 nIndex)1697 uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex)
1698 {
1699     ScUnoGuard aGuard;
1700     IsObjectValid();
1701     uno::Reference<XAccessible> xAccessible;
1702 
1703     if ( mpViewShell )
1704     {
1705         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1706         ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1707 
1708         if ( nIndex < aCount.nBackShapes )
1709         {
1710             xAccessible = GetShapeChilds()->GetBackShape(nIndex);
1711         }
1712         else if ( nIndex < aCount.nBackShapes + aCount.nHeaders )
1713         {
1714             if ( !mpHeader )
1715             {
1716                 mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, nIndex );
1717                 mpHeader->acquire();
1718             }
1719 
1720             xAccessible = mpHeader;
1721         }
1722         else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables )
1723         {
1724             if ( !mpTable )
1725             {
1726                 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1727                 mpTable->acquire();
1728                 mpTable->Init();
1729             }
1730             xAccessible = mpTable;
1731         }
1732         else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs )
1733         {
1734             xAccessible = GetNotesChilds()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders);
1735         }
1736         else if ( (nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters) )
1737         {
1738             if ( !mpFooter )
1739             {
1740                 mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, nIndex );
1741                 mpFooter->acquire();
1742             }
1743             xAccessible = mpFooter;
1744         }
1745         else
1746         {
1747             sal_Int32 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters));
1748             if (nIdx < aCount.nForeShapes)
1749                 xAccessible = GetShapeChilds()->GetForeShape(nIdx);
1750             else
1751                 xAccessible = GetShapeChilds()->GetControl(nIdx - aCount.nForeShapes);
1752         }
1753     }
1754 
1755     if ( !xAccessible.is() )
1756         throw lang::IndexOutOfBoundsException();
1757 
1758     return xAccessible;
1759 }
1760 
1761     /// Return the set of current states.
getAccessibleStateSet(void)1762 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleStateSet(void)
1763 {
1764     ScUnoGuard aGuard;
1765     uno::Reference<XAccessibleStateSet> xParentStates;
1766     if (getAccessibleParent().is())
1767     {
1768         uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1769         xParentStates = xParentContext->getAccessibleStateSet();
1770     }
1771     utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1772     if (IsDefunc(xParentStates))
1773         pStateSet->AddState(AccessibleStateType::DEFUNC);
1774     else
1775     {
1776         // never editable
1777         pStateSet->AddState(AccessibleStateType::ENABLED);
1778         pStateSet->AddState(AccessibleStateType::OPAQUE);
1779         if (isShowing())
1780             pStateSet->AddState(AccessibleStateType::SHOWING);
1781         if (isVisible())
1782             pStateSet->AddState(AccessibleStateType::VISIBLE);
1783     }
1784     return pStateSet;
1785 }
1786 
1787     //=====  XServiceInfo  ====================================================
1788 
getImplementationName(void)1789 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::getImplementationName(void)
1790 {
1791     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview"));
1792 }
1793 
getSupportedServiceNames(void)1794 uno::Sequence< ::rtl::OUString> SAL_CALL ScAccessibleDocumentPagePreview::getSupportedServiceNames(void)
1795 {
1796     uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
1797     sal_Int32 nOldSize(aSequence.getLength());
1798     aSequence.realloc(nOldSize + 1);
1799     ::rtl::OUString* pNames = aSequence.getArray();
1800 
1801     pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView"));
1802 
1803     return aSequence;
1804 }
1805 
1806 //=====  XTypeProvider  =======================================================
1807 
1808 uno::Sequence<sal_Int8> SAL_CALL
getImplementationId(void)1809     ScAccessibleDocumentPagePreview::getImplementationId(void)
1810 {
1811     ScUnoGuard aGuard;
1812     IsObjectValid();
1813     static uno::Sequence<sal_Int8> aId;
1814     if (aId.getLength() == 0)
1815     {
1816         aId.realloc (16);
1817         rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
1818     }
1819     return aId;
1820 }
1821 
1822 //=====  internal  ========================================================
1823 
createAccessibleDescription(void)1824 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleDescription(void)
1825 {
1826     rtl::OUString sDescription = String(ScResId(STR_ACC_PREVIEWDOC_DESCR));
1827     return sDescription;
1828 }
1829 
createAccessibleName(void)1830 ::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleName(void)
1831 {
1832     rtl::OUString sName = String(ScResId(STR_ACC_PREVIEWDOC_NAME));
1833     return sName;
1834 }
1835 
GetBoundingBoxOnScreen() const1836 Rectangle ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const
1837 {
1838     Rectangle aRect;
1839     if (mpViewShell)
1840     {
1841         Window* pWindow = mpViewShell->GetWindow();
1842         if (pWindow)
1843             aRect = pWindow->GetWindowExtentsRelative(NULL);
1844     }
1845     return aRect;
1846 }
1847 
GetBoundingBox() const1848 Rectangle ScAccessibleDocumentPagePreview::GetBoundingBox() const
1849 {
1850     Rectangle aRect;
1851     if (mpViewShell)
1852     {
1853         Window* pWindow = mpViewShell->GetWindow();
1854         if (pWindow)
1855             aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
1856     }
1857     return aRect;
1858 }
1859 
IsDefunc(const uno::Reference<XAccessibleStateSet> & rxParentStates)1860 sal_Bool ScAccessibleDocumentPagePreview::IsDefunc(
1861     const uno::Reference<XAccessibleStateSet>& rxParentStates)
1862 {
1863     return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
1864         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
1865 }
1866 
GetNotesChilds()1867 ScNotesChilds* ScAccessibleDocumentPagePreview::GetNotesChilds()
1868 {
1869     if (!mpNotesChilds && mpViewShell)
1870     {
1871         mpNotesChilds = new ScNotesChilds(mpViewShell, this);
1872 
1873         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1874         ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1875 
1876         //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1877         mpNotesChilds->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders);
1878     }
1879     return mpNotesChilds;
1880 }
1881 
GetShapeChilds()1882 ScShapeChilds* ScAccessibleDocumentPagePreview::GetShapeChilds()
1883 {
1884     if (!mpShapeChilds && mpViewShell)
1885     {
1886         mpShapeChilds = new ScShapeChilds(mpViewShell, this);
1887         mpShapeChilds->Init();
1888     }
1889 
1890     return mpShapeChilds;
1891 }
1892 
getAccessibleName(void)1893 ::rtl::OUString ScAccessibleDocumentPagePreview::getAccessibleName(void)
1894 {
1895     rtl::OUString sName = String(ScResId(STR_ACC_DOC_SPREADSHEET));
1896     ScDocument* pScDoc = mpViewShell->GetDocument();
1897     if ( pScDoc )
1898     {
1899         rtl::OUString sFileName = pScDoc->getDocAccTitle();
1900         if ( !sFileName.getLength() )
1901         {
1902             SfxObjectShell* pObjSh = pScDoc->GetDocumentShell();
1903             if ( pObjSh )
1904             {
1905                 sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME );
1906             }
1907         }
1908         if ( sFileName.getLength() )
1909         {
1910             sName = sFileName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName;
1911             sName += String(ScResId(STR_ACC_DOC_PREVIEW_SUFFIX));
1912 
1913         }
1914     }
1915 
1916     return sName;
1917 }
1918 
1919 //UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable()
1920 //UNUSED2009-05 {
1921 //UNUSED2009-05     if (!mpTable)
1922 //UNUSED2009-05     {
1923 //UNUSED2009-05         if ( mpViewShell )
1924 //UNUSED2009-05         {
1925 //UNUSED2009-05             const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1926 //UNUSED2009-05             ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1927 //UNUSED2009-05             //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1928 //UNUSED2009-05             sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
1929 //UNUSED2009-05
1930 //UNUSED2009-05             mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
1931 //UNUSED2009-05             mpTable->acquire();
1932 //UNUSED2009-05             mpTable->Init();
1933 //UNUSED2009-05         }
1934 //UNUSED2009-05     }
1935 //UNUSED2009-05     return mpTable;
1936 //UNUSED2009-05 }
1937 
1938 //UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged()
1939 //UNUSED2009-05 {
1940 //UNUSED2009-05     if (mpViewShell)
1941 //UNUSED2009-05     {
1942 //UNUSED2009-05         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
1943 //UNUSED2009-05         ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
1944 //UNUSED2009-05         //! order is background shapes, header, table or notes, footer, foreground shapes, controls
1945 //UNUSED2009-05         if(mpHeader)
1946 //UNUSED2009-05             mpHeader->SetCurrentIndexInParent(aCount.nBackShapes);
1947 //UNUSED2009-05         if (mpTable)
1948 //UNUSED2009-05             mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders);
1949 //UNUSED2009-05         if (mpFooter)
1950 //UNUSED2009-05             mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs);
1951 //UNUSED2009-05
1952 //UNUSED2009-05         if (mpNotesChilds)
1953 //UNUSED2009-05             mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders);
1954 //UNUSED2009-05     }
1955 //UNUSED2009-05 }
1956