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