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