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