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