1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sdext.hxx"
25
26 #include "PresenterAccessibility.hxx"
27 #include "PresenterTextView.hxx"
28 #include "PresenterConfigurationAccess.hxx"
29 #include "PresenterNotesView.hxx"
30 #include "PresenterPaneBase.hxx"
31 #include "PresenterPaneContainer.hxx"
32 #include "PresenterPaneFactory.hxx"
33 #include "PresenterViewFactory.hxx"
34
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
36 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
39 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
40 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
41 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
42 #include <com/sun/star/accessibility/XAccessibleText.hpp>
43 #include <com/sun/star/drawing/framework/ResourceId.hpp>
44 #include <com/sun/star/drawing/framework/XPane.hpp>
45 #include <com/sun/star/drawing/framework/XView.hpp>
46 #include <cppuhelper/compbase1.hxx>
47 #include <cppuhelper/compbase5.hxx>
48 #include <cppuhelper/implbase1.hxx>
49 #include <boost/bind.hpp>
50
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::accessibility;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::drawing::framework;
55 using ::rtl::OUString;
56
57 #define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
58
59 #define VERBOSE
60
61 //===== PresenterAccessibleObject =============================================
62
63 namespace sdext { namespace presenter {
64
65 namespace {
66 typedef ::cppu::WeakComponentImplHelper5 <
67 cssa::XAccessible,
68 cssa::XAccessibleContext,
69 cssa::XAccessibleComponent,
70 cssa::XAccessibleEventBroadcaster,
71 css::awt::XWindowListener
72 > PresenterAccessibleObjectInterfaceBase;
73 }
74
75 class PresenterAccessible::AccessibleObject
76 : public ::cppu::BaseMutex,
77 public PresenterAccessibleObjectInterfaceBase
78 {
79 public:
80 AccessibleObject (
81 const css::lang::Locale aLocale,
82 const sal_Int16 nRole,
83 const ::rtl::OUString& rsName);
84 void LateInitialization (void);
85
86 virtual ~AccessibleObject (void);
87
88 virtual void SetWindow (
89 const cssu::Reference<css::awt::XWindow>& rxContentWindow,
90 const cssu::Reference<css::awt::XWindow>& rxBorderWindow);
91 void SetAccessibleParent (const cssu::Reference<cssa::XAccessible>& rxAccessibleParent);
92
93 virtual void SAL_CALL disposing (void);
94
95 void NotifyCurrentSlideChange (const sal_Int32 nCurrentSlideIndex);
96
97 void AddChild (const ::rtl::Reference<AccessibleObject>& rpChild);
98 void RemoveChild (const ::rtl::Reference<AccessibleObject>& rpChild);
99
100 void SetIsFocused (const bool bIsFocused);
101 void SetAccessibleName (const ::rtl::OUString& rsName);
102
103 void FireAccessibleEvent (
104 const sal_Int16 nEventId,
105 const cssu::Any& rOldValue,
106 const cssu::Any& rNewValue);
107
108 void UpdateStateSet (void);
109
110
111 //----- XAccessible -------------------------------------------------------
112
113 virtual cssu::Reference<cssa::XAccessibleContext> SAL_CALL
114 getAccessibleContext (void)
115 throw (cssu::RuntimeException);
116
117
118 //----- XAccessibleContext ----------------------------------------------
119
120 virtual sal_Int32 SAL_CALL getAccessibleChildCount (void)
121 throw (cssu::RuntimeException);
122
123 virtual cssu::Reference< cssa::XAccessible> SAL_CALL
124 getAccessibleChild (sal_Int32 nIndex)
125 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
126
127 virtual cssu::Reference< cssa::XAccessible> SAL_CALL getAccessibleParent (void)
128 throw (cssu::RuntimeException);
129
130 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent (void)
131 throw (cssu::RuntimeException);
132
133 virtual sal_Int16 SAL_CALL getAccessibleRole (void)
134 throw (cssu::RuntimeException);
135
136 virtual ::rtl::OUString SAL_CALL getAccessibleDescription (void)
137 throw (cssu::RuntimeException);
138
139 virtual ::rtl::OUString SAL_CALL getAccessibleName (void)
140 throw (cssu::RuntimeException);
141
142 virtual cssu::Reference<cssa::XAccessibleRelationSet> SAL_CALL
143 getAccessibleRelationSet (void)
144 throw (cssu::RuntimeException);
145
146 virtual cssu::Reference<cssa::XAccessibleStateSet> SAL_CALL
147 getAccessibleStateSet (void)
148 throw (cssu::RuntimeException);
149
150 virtual css::lang::Locale SAL_CALL getLocale (void)
151 throw (cssu::RuntimeException,
152 cssa::IllegalAccessibleComponentStateException);
153
154
155 //----- XAccessibleComponent --------------------------------------------
156
157 virtual sal_Bool SAL_CALL containsPoint (
158 const css::awt::Point& aPoint)
159 throw (cssu::RuntimeException);
160
161 virtual cssu::Reference<cssa::XAccessible> SAL_CALL
162 getAccessibleAtPoint (
163 const css::awt::Point& aPoint)
164 throw (cssu::RuntimeException);
165
166 virtual css::awt::Rectangle SAL_CALL getBounds (void)
167 throw (cssu::RuntimeException);
168
169 virtual css::awt::Point SAL_CALL getLocation (void)
170 throw (cssu::RuntimeException);
171
172 virtual css::awt::Point SAL_CALL getLocationOnScreen (void)
173 throw (cssu::RuntimeException);
174
175 virtual css::awt::Size SAL_CALL getSize (void)
176 throw (cssu::RuntimeException);
177
178 virtual void SAL_CALL grabFocus (void)
179 throw (cssu::RuntimeException);
180
181 virtual sal_Int32 SAL_CALL getForeground (void)
182 throw (cssu::RuntimeException);
183
184 virtual sal_Int32 SAL_CALL getBackground (void)
185 throw (cssu::RuntimeException);
186
187
188 //----- XAccessibleEventBroadcaster --------------------------------------
189
190 virtual void SAL_CALL addEventListener (
191 const cssu::Reference<cssa::XAccessibleEventListener>& rxListener)
192 throw (cssu::RuntimeException);
193
194 virtual void SAL_CALL removeEventListener (
195 const cssu::Reference<cssa::XAccessibleEventListener>& rxListener)
196 throw (cssu::RuntimeException);
197
198 using PresenterAccessibleObjectInterfaceBase::addEventListener;
199 using PresenterAccessibleObjectInterfaceBase::removeEventListener;
200
201 //----- XWindowListener ---------------------------------------------------
202
203 virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
204 throw (cssu::RuntimeException);
205
206 virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
207 throw (cssu::RuntimeException);
208
209 virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
210 throw (cssu::RuntimeException);
211
212 virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
213 throw (cssu::RuntimeException);
214
215
216 //----- XEventListener ----------------------------------------------------
217
218 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
219 throw (cssu::RuntimeException);
220
221
222 protected:
223 ::rtl::OUString msName;
224 cssu::Reference<css::awt::XWindow2> mxContentWindow;
225 cssu::Reference<css::awt::XWindow2> mxBorderWindow;
226 const css::lang::Locale maLocale;
227 const sal_Int16 mnRole;
228 sal_uInt32 mnStateSet;
229 bool mbIsFocused;
230 cssu::Reference<cssa::XAccessible> mxParentAccessible;
231 ::std::vector<rtl::Reference<AccessibleObject> > maChildren;
232 ::std::vector<Reference<XAccessibleEventListener> > maListeners;
233
234 virtual awt::Point GetRelativeLocation (void);
235 virtual awt::Size GetSize (void);
236 virtual awt::Point GetAbsoluteParentLocation (void);
237
238 virtual bool GetWindowState (const sal_Int16 nType) const;
239
240 void UpdateState (const sal_Int16 aState, const bool bValue);
241
242 sal_Bool IsDisposed (void) const;
243
244 void ThrowIfDisposed (void) const
245 throw (css::lang::DisposedException);
246
247 enum ExceptionType { ET_Runtime, ET_Disposed, ET_IndexOutOfBounds };
248 void ThrowException (const sal_Char* pMessage, const ExceptionType eExceptionType) const;
249 };
250
251
252
253
254 //===== AccessibleStateSet ====================================================
255
256 namespace {
257 typedef ::cppu::WeakComponentImplHelper1 <
258 cssa::XAccessibleStateSet
259 > AccessibleStateSetInterfaceBase;
260 }
261
262 class AccessibleStateSet
263 : public ::cppu::BaseMutex,
264 public AccessibleStateSetInterfaceBase
265 {
266 public:
267 AccessibleStateSet (const sal_Int32 nStateSet);
268 virtual ~AccessibleStateSet (void);
269
270 static sal_uInt32 GetStateMask (const sal_Int16 nType);
271
272 //----- XAccessibleStateSet -----------------------------------------------
273
274 virtual sal_Bool SAL_CALL isEmpty (void)
275 throw (cssu::RuntimeException);
276
277 virtual sal_Bool SAL_CALL contains (sal_Int16 nState)
278 throw (cssu::RuntimeException);
279
280 virtual sal_Bool SAL_CALL containsAll (const cssu::Sequence<sal_Int16>& rStateSet)
281 throw (cssu::RuntimeException);
282
283 virtual cssu::Sequence<sal_Int16> SAL_CALL getStates (void)
284 throw (cssu::RuntimeException);
285
286 private:
287 const sal_Int32 mnStateSet;
288 };
289
290
291
292
293 //===== AccessibleRelationSet =================================================
294
295 namespace {
296 typedef ::cppu::WeakComponentImplHelper1 <
297 cssa::XAccessibleRelationSet
298 > AccessibleRelationSetInterfaceBase;
299 }
300
301 class AccessibleRelationSet
302 : public ::cppu::BaseMutex,
303 public AccessibleRelationSetInterfaceBase
304 {
305 public:
306 AccessibleRelationSet (void);
307 virtual ~AccessibleRelationSet (void);
308
309 void AddRelation (
310 const sal_Int16 nRelationType,
311 const Reference<XInterface>& rxObject);
312
313
314 //----- XAccessibleRelationSet --------------------------------------------
315
316 virtual sal_Int32 SAL_CALL getRelationCount (void)
317 throw (cssu::RuntimeException);
318
319 virtual AccessibleRelation SAL_CALL getRelation (sal_Int32 nIndex)
320 throw (cssu::RuntimeException, css::lang::IndexOutOfBoundsException);
321
322 virtual sal_Bool SAL_CALL containsRelation (sal_Int16 nRelationType)
323 throw (cssu::RuntimeException);
324
325 virtual AccessibleRelation SAL_CALL getRelationByType (sal_Int16 nRelationType)
326 throw (cssu::RuntimeException);
327
328 private:
329 ::std::vector<AccessibleRelation> maRelations;
330 };
331
332
333
334
335 //===== PresenterAccessibleParagraph ==========================================
336
337 namespace {
338 typedef ::cppu::ImplInheritanceHelper1 <
339 PresenterAccessible::AccessibleObject,
340 cssa::XAccessibleText
341 > PresenterAccessibleParagraphInterfaceBase;
342 }
343
344
345
346
347 class PresenterAccessible::AccessibleParagraph
348 : public PresenterAccessibleParagraphInterfaceBase
349 {
350 public:
351 AccessibleParagraph (
352 const css::lang::Locale aLocale,
353 const sal_Int16 nRole,
354 const ::rtl::OUString& rsName,
355 const SharedPresenterTextParagraph& rpParagraph,
356 const sal_Int32 nParagraphIndex);
357
358 virtual ~AccessibleParagraph (void);
359
360
361 //----- XAccessibleContext ------------------------------------------------
362
363 virtual cssu::Reference<cssa::XAccessibleRelationSet> SAL_CALL
364 getAccessibleRelationSet (void)
365 throw (cssu::RuntimeException);
366
367
368 //----- XAccessibleText ---------------------------------------------------
369
370 virtual sal_Int32 SAL_CALL getCaretPosition (void)
371 throw (cssu::RuntimeException);
372
373 virtual sal_Bool SAL_CALL setCaretPosition (sal_Int32 nIndex)
374 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException);
375
376 virtual sal_Unicode SAL_CALL getCharacter (sal_Int32 nIndex)
377 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException);
378
379 virtual cssu::Sequence<css::beans::PropertyValue> SAL_CALL
380 getCharacterAttributes (
381 ::sal_Int32 nIndex,
382 const cssu::Sequence<rtl::OUString>& rRequestedAttributes)
383 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
384
385 virtual css::awt::Rectangle SAL_CALL getCharacterBounds (sal_Int32 nIndex)
386 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
387
388 virtual sal_Int32 SAL_CALL getCharacterCount (void)
389 throw (cssu::RuntimeException);
390
391 virtual sal_Int32 SAL_CALL getIndexAtPoint (const css::awt::Point& rPoint)
392 throw (cssu::RuntimeException);
393
394 virtual ::rtl::OUString SAL_CALL getSelectedText (void)
395 throw (cssu::RuntimeException);
396
397 virtual sal_Int32 SAL_CALL getSelectionStart (void)
398 throw (cssu::RuntimeException);
399
400 virtual sal_Int32 SAL_CALL getSelectionEnd (void)
401 throw (cssu::RuntimeException);
402
403 virtual sal_Bool SAL_CALL setSelection (sal_Int32 nStartIndex, sal_Int32 nEndIndex)
404 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
405
406 virtual ::rtl::OUString SAL_CALL getText (void)
407 throw (cssu::RuntimeException);
408
409 virtual ::rtl::OUString SAL_CALL getTextRange (
410 sal_Int32 nStartIndex,
411 sal_Int32 nEndIndex)
412 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
413
414 virtual cssa::TextSegment SAL_CALL getTextAtIndex (
415 sal_Int32 nIndex,
416 sal_Int16 nTextType)
417 throw (css::lang::IndexOutOfBoundsException,
418 css::lang::IllegalArgumentException,
419 cssu::RuntimeException);
420
421 virtual cssa::TextSegment SAL_CALL getTextBeforeIndex (
422 sal_Int32 nIndex,
423 sal_Int16 nTextType)
424 throw (css::lang::IndexOutOfBoundsException,
425 css::lang::IllegalArgumentException,
426 cssu::RuntimeException);
427
428 virtual cssa::TextSegment SAL_CALL getTextBehindIndex (
429 sal_Int32 nIndex,
430 sal_Int16 nTextType)
431 throw (css::lang::IndexOutOfBoundsException,
432 css::lang::IllegalArgumentException,
433 cssu::RuntimeException);
434
435 virtual ::sal_Bool SAL_CALL copyText (sal_Int32 nStartIndex, sal_Int32 nEndIndex)
436 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
437
438
439 protected:
440 virtual awt::Point GetRelativeLocation (void);
441 virtual awt::Size GetSize (void);
442 virtual awt::Point GetAbsoluteParentLocation (void);
443 virtual bool GetWindowState (const sal_Int16 nType) const;
444
445 private:
446 SharedPresenterTextParagraph mpParagraph;
447 const sal_Int32 mnParagraphIndex;
448 };
449
450
451
452
453 //===== AccessibleConsole =====================================================
454
455 class AccessibleConsole
456 {
457 public:
Create(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const lang::Locale aLocale)458 static rtl::Reference<PresenterAccessible::AccessibleObject> Create (
459 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
460 const lang::Locale aLocale)
461 {
462 OUString sName (A2S("Presenter Console"));
463 PresenterConfigurationAccess aConfiguration (
464 rxContext,
465 OUString::createFromAscii("/org.openoffice.Office.PresenterScreen/"),
466 PresenterConfigurationAccess::READ_ONLY);
467 aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Console/String"))
468 >>= sName;
469
470 rtl::Reference<PresenterAccessible::AccessibleObject> pObject (
471 new PresenterAccessible::AccessibleObject(
472 aLocale, AccessibleRole::PANEL, sName));
473 pObject->LateInitialization();
474 pObject->UpdateStateSet();
475
476 return pObject;
477 }
478 };
479
480
481
482
483 //===== AccessiblePreview =====================================================
484
485 class AccessiblePreview
486 {
487 public:
Create(const Reference<css::uno::XComponentContext> & rxContext,const lang::Locale aLocale,const Reference<awt::XWindow> & rxContentWindow,const Reference<awt::XWindow> & rxBorderWindow)488 static rtl::Reference<PresenterAccessible::AccessibleObject> Create (
489 const Reference<css::uno::XComponentContext>& rxContext,
490 const lang::Locale aLocale,
491 const Reference<awt::XWindow>& rxContentWindow,
492 const Reference<awt::XWindow>& rxBorderWindow)
493 {
494 OUString sName (A2S("Presenter Notes Window"));
495 {
496 PresenterConfigurationAccess aConfiguration (
497 rxContext,
498 OUString::createFromAscii("/org.openoffice.Office.PresenterScreen/"),
499 PresenterConfigurationAccess::READ_ONLY);
500 aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Preview/String"))
501 >>= sName;
502 }
503
504 rtl::Reference<PresenterAccessible::AccessibleObject> pObject (
505 new PresenterAccessible::AccessibleObject(
506 aLocale,
507 AccessibleRole::LABEL,
508 sName));
509 pObject->LateInitialization();
510 pObject->UpdateStateSet();
511 pObject->SetWindow(rxContentWindow, rxBorderWindow);
512
513 return pObject;
514 }
515 };
516
517
518
519
520 //===== AccessibleNotes =======================================================
521
522 class AccessibleNotes : public PresenterAccessible::AccessibleObject
523 {
524 public:
525 AccessibleNotes (
526 const css::lang::Locale aLocale,
527 const sal_Int16 nRole,
528 const ::rtl::OUString& rsName);
529
530
531 static rtl::Reference<PresenterAccessible::AccessibleObject> Create (
532 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
533 const lang::Locale aLocale,
534 const Reference<awt::XWindow>& rxContentWindow,
535 const Reference<awt::XWindow>& rxBorderWindow,
536 const ::boost::shared_ptr<PresenterTextView>& rpTextView);
537
538 void SetTextView (const ::boost::shared_ptr<PresenterTextView>& rpTextView);
539
540 virtual void SetWindow (
541 const cssu::Reference<css::awt::XWindow>& rxContentWindow,
542 const cssu::Reference<css::awt::XWindow>& rxBorderWindow);
543
544 private:
545 ::boost::shared_ptr<PresenterTextView> mpTextView;
546
547 void NotifyCaretChange (
548 const sal_Int32 nOldParagraphIndex,
549 const sal_Int32 nOldCharacterIndex,
550 const sal_Int32 nNewParagraphIndex,
551 const sal_Int32 nNewCharacterIndex);
552 void HandleTextChange (void);
553 };
554
555
556
557
558 //===== AccessibleFocusManager ================================================
559
560 /** A singleton class that makes sure that only one accessibility object in
561 the PresenterConsole hierarchy has the focus.
562 */
563 class AccessibleFocusManager
564 {
565 public:
566 static ::boost::shared_ptr<AccessibleFocusManager> Instance (void);
567
568 void AddFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
569 void RemoveFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
570
571 void FocusObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
572
573 private:
574 static ::boost::shared_ptr<AccessibleFocusManager> mpInstance;
575 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > maFocusableObjects;
576
577 AccessibleFocusManager (void);
578 };
579
580
581
582
583 //===== PresenterAccessible ===================================================
584
PresenterAccessible(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const::rtl::Reference<PresenterController> & rpPresenterController,const Reference<drawing::framework::XPane> & rxMainPane)585 PresenterAccessible::PresenterAccessible (
586 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
587 const ::rtl::Reference<PresenterController>& rpPresenterController,
588 const Reference<drawing::framework::XPane>& rxMainPane)
589 : PresenterAccessibleInterfaceBase(m_aMutex),
590 mxComponentContext(rxContext),
591 mpPresenterController(rpPresenterController),
592 mxMainPaneId(rxMainPane.is() ? rxMainPane->getResourceId() : Reference<XResourceId>()),
593 mxMainPane(rxMainPane, UNO_QUERY),
594 mxMainWindow(),
595 mxPreviewContentWindow(),
596 mxPreviewBorderWindow(),
597 mxNotesContentWindow(),
598 mxNotesBorderWindow(),
599 mpAccessibleConsole(),
600 mpAccessiblePreview(),
601 mpAccessibleNotes(),
602 mxAccessibleParent()
603 {
604 if (mxMainPane.is())
605 mxMainPane->setAccessible(this);
606 }
607
608
609
610
~PresenterAccessible(void)611 PresenterAccessible::~PresenterAccessible (void)
612 {
613 }
614
615
616
617
GetPreviewPane(void) const618 PresenterPaneContainer::SharedPaneDescriptor PresenterAccessible::GetPreviewPane (void) const
619 {
620 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane;
621
622 if ( ! mpPresenterController.is())
623 return pPreviewPane;
624
625 rtl::Reference<PresenterPaneContainer> pContainer (mpPresenterController->GetPaneContainer());
626 if ( ! pContainer.is())
627 return pPreviewPane;
628
629 pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
630 Reference<drawing::framework::XPane> xPreviewPane;
631 if (pPreviewPane)
632 xPreviewPane = pPreviewPane->mxPane.get();
633 if ( ! xPreviewPane.is())
634 {
635 pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msSlideSorterPaneURL);
636 }
637 return pPreviewPane;
638 }
639
640
641
642
UpdateAccessibilityHierarchy(void)643 void PresenterAccessible::UpdateAccessibilityHierarchy (void)
644 {
645 if ( ! mpPresenterController.is())
646 return;
647
648 Reference<drawing::framework::XConfigurationController> xConfigurationController(
649 mpPresenterController->GetConfigurationController());
650 if ( ! xConfigurationController.is())
651 return;
652
653 rtl::Reference<PresenterPaneContainer> pPaneContainer (
654 mpPresenterController->GetPaneContainer());
655 if ( ! pPaneContainer.is())
656 return;
657
658 if ( ! mpAccessibleConsole.is())
659 return;
660
661 // Get the preview pane (standard or notes view) or the slide overview
662 // pane.
663 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane(GetPreviewPane());
664 Reference<drawing::framework::XPane> xPreviewPane;
665 if (pPreviewPane)
666 xPreviewPane = pPreviewPane->mxPane.get();
667
668 // Get the notes pane.
669 PresenterPaneContainer::SharedPaneDescriptor pNotesPane(
670 pPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
671 Reference<drawing::framework::XPane> xNotesPane;
672 if (pNotesPane)
673 xNotesPane = pNotesPane->mxPane.get();
674
675 // Get the notes view.
676 Reference<drawing::framework::XView> xNotesView;
677 if (pNotesPane)
678 xNotesView = pNotesPane->mxView;
679 rtl::Reference<PresenterNotesView> pNotesView (
680 dynamic_cast<PresenterNotesView*>(xNotesView.get()));
681
682 UpdateAccessibilityHierarchy(
683 pPreviewPane ? pPreviewPane->mxContentWindow : Reference<awt::XWindow>(),
684 pPreviewPane ? pPreviewPane->mxBorderWindow : Reference<awt::XWindow>(),
685 (pPreviewPane&&pPreviewPane->mxPane.is()) ? pPreviewPane->mxPane->GetTitle() : OUString(),
686 pNotesPane ? pNotesPane->mxContentWindow : Reference<awt::XWindow>(),
687 pNotesPane ? pNotesPane->mxBorderWindow : Reference<awt::XWindow>(),
688 pNotesView.is()
689 ? pNotesView->GetTextView()
690 : ::boost::shared_ptr<PresenterTextView>());
691 }
692
693
694
695
696
UpdateAccessibilityHierarchy(const Reference<awt::XWindow> & rxPreviewContentWindow,const Reference<awt::XWindow> & rxPreviewBorderWindow,const::rtl::OUString & rsTitle,const Reference<awt::XWindow> & rxNotesContentWindow,const Reference<awt::XWindow> & rxNotesBorderWindow,const::boost::shared_ptr<PresenterTextView> & rpNotesTextView)697 void PresenterAccessible::UpdateAccessibilityHierarchy (
698 const Reference<awt::XWindow>& rxPreviewContentWindow,
699 const Reference<awt::XWindow>& rxPreviewBorderWindow,
700 const ::rtl::OUString& rsTitle,
701 const Reference<awt::XWindow>& rxNotesContentWindow,
702 const Reference<awt::XWindow>& rxNotesBorderWindow,
703 const ::boost::shared_ptr<PresenterTextView>& rpNotesTextView)
704 {
705 if ( ! mpAccessibleConsole.is())
706 return;
707
708 if (mxPreviewContentWindow != rxPreviewContentWindow)
709 {
710 if (mpAccessiblePreview.is())
711 {
712 mpAccessibleConsole->RemoveChild(mpAccessiblePreview);
713 mpAccessiblePreview = NULL;
714 }
715
716 mxPreviewContentWindow = rxPreviewContentWindow;
717 mxPreviewBorderWindow = rxPreviewBorderWindow;
718
719 if (mxPreviewContentWindow.is())
720 {
721 mpAccessiblePreview = AccessiblePreview::Create(
722 mxComponentContext,
723 lang::Locale(),
724 mxPreviewContentWindow,
725 mxPreviewBorderWindow);
726 mpAccessibleConsole->AddChild(mpAccessiblePreview);
727 mpAccessiblePreview->SetAccessibleName(rsTitle);
728 }
729 }
730
731 if (mxNotesContentWindow != rxNotesContentWindow)
732 {
733 if (mpAccessibleNotes.is())
734 {
735 mpAccessibleConsole->RemoveChild(mpAccessibleConsole.get());
736 mpAccessibleNotes = NULL;
737 }
738
739 mxNotesContentWindow = rxNotesContentWindow;
740 mxNotesBorderWindow = rxNotesBorderWindow;
741
742 if (mxNotesContentWindow.is())
743 {
744 mpAccessibleNotes = AccessibleNotes::Create(
745 mxComponentContext,
746 lang::Locale(),
747 mxNotesContentWindow,
748 mxNotesBorderWindow,
749 rpNotesTextView);
750 mpAccessibleConsole->AddChild(mpAccessibleNotes.get());
751 }
752 }
753 }
754
755
756
757
NotifyCurrentSlideChange(const sal_Int32 nCurrentSlideIndex,const sal_Int32 nSlideCount)758 void PresenterAccessible::NotifyCurrentSlideChange (
759 const sal_Int32 nCurrentSlideIndex,
760 const sal_Int32 nSlideCount)
761 {
762 (void)nCurrentSlideIndex;
763 (void)nSlideCount;
764
765 if (mpAccessiblePreview.is())
766 {
767 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane (GetPreviewPane());
768 mpAccessiblePreview->SetAccessibleName(
769 (pPreviewPane&&pPreviewPane->mxPane.is()
770 ? pPreviewPane->mxPane->GetTitle()
771 : rtl::OUString()));
772 }
773
774 // Play some focus ping-pong to trigger AT tools.
775 //AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
776 AccessibleFocusManager::Instance()->FocusObject(mpAccessiblePreview);
777 }
778
779
780
781
IsAccessibilityActive(void) const782 bool PresenterAccessible::IsAccessibilityActive (void) const
783 {
784 return mpAccessibleConsole.is();
785 }
786
787
788
789
disposing(void)790 void SAL_CALL PresenterAccessible::disposing (void)
791 {
792 UpdateAccessibilityHierarchy(
793 NULL,
794 NULL,
795 OUString(),
796 NULL,
797 NULL,
798 ::boost::shared_ptr<PresenterTextView>());
799
800 if (mxMainWindow.is())
801 {
802 mxMainWindow->removeFocusListener(this);
803
804 if (mxMainPane.is())
805 mxMainPane->setAccessible(NULL);
806 }
807
808 mpAccessiblePreview = NULL;
809 mpAccessibleNotes = NULL;
810 mpAccessibleConsole = NULL;
811 }
812
813
814
815
816 //----- XAccessible -----------------------------------------------------------
817
getAccessibleContext(void)818 Reference<XAccessibleContext> SAL_CALL PresenterAccessible::getAccessibleContext (void)
819 throw (cssu::RuntimeException)
820 {
821 if ( ! mpAccessibleConsole.is())
822 {
823 Reference<XPane> xMainPane (mxMainPane, UNO_QUERY);
824 if (xMainPane.is())
825 {
826 mxMainWindow = Reference<awt::XWindow>(xMainPane->getWindow(), UNO_QUERY);
827 mxMainWindow->addFocusListener(this);
828 }
829 mpAccessibleConsole = AccessibleConsole::Create(
830 mxComponentContext, css::lang::Locale());
831 mpAccessibleConsole->SetWindow(mxMainWindow, NULL);
832 mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent);
833 UpdateAccessibilityHierarchy();
834 if (mpPresenterController.is())
835 mpPresenterController->SetAccessibilityActiveState(true);
836 }
837 return mpAccessibleConsole->getAccessibleContext();
838 }
839
840
841
842
843
844 //----- XFocusListener ----------------------------------------------------
845
focusGained(const css::awt::FocusEvent & rEvent)846 void SAL_CALL PresenterAccessible::focusGained (const css::awt::FocusEvent& rEvent)
847 throw (cssu::RuntimeException)
848 {
849 (void)rEvent;
850
851 #ifdef VERBOSE
852 OSL_TRACE("PresenterAccessible::focusGained at %x and window %x\r", this,
853 mxMainWindow.get());
854 #endif
855
856 AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
857 }
858
859
860
861
focusLost(const css::awt::FocusEvent & rEvent)862 void SAL_CALL PresenterAccessible::focusLost (const css::awt::FocusEvent& rEvent)
863 throw (cssu::RuntimeException)
864 {
865 (void)rEvent;
866
867 #ifdef VERBOSE
868 OSL_TRACE("PresenterAccessible::focusLost at %x\r", this);
869 #endif
870
871 AccessibleFocusManager::Instance()->FocusObject(NULL);
872 }
873
874
875
876
877 //----- XEventListener ----------------------------------------------------
878
disposing(const css::lang::EventObject & rEvent)879 void SAL_CALL PresenterAccessible::disposing (const css::lang::EventObject& rEvent)
880 throw (cssu::RuntimeException)
881 {
882 if (rEvent.Source == mxMainWindow)
883 mxMainWindow = NULL;
884 }
885
886
887
888
889 //----- XInitialize -----------------------------------------------------------
890
initialize(const cssu::Sequence<cssu::Any> & rArguments)891 void SAL_CALL PresenterAccessible::initialize (const cssu::Sequence<cssu::Any>& rArguments)
892 throw (cssu::RuntimeException)
893 {
894 if (rArguments.getLength() >= 1)
895 {
896 mxAccessibleParent = Reference<XAccessible>(rArguments[0], UNO_QUERY);
897 if (mpAccessibleConsole.is())
898 mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent);
899 }
900 }
901
902
903
904
905 //===== PresenterAccessible::AccessibleObject =========================================
906
AccessibleObject(const lang::Locale aLocale,const sal_Int16 nRole,const OUString & rsName)907 PresenterAccessible::AccessibleObject::AccessibleObject (
908 const lang::Locale aLocale,
909 const sal_Int16 nRole,
910 const OUString& rsName)
911 : PresenterAccessibleObjectInterfaceBase(m_aMutex),
912 msName(rsName),
913 mxContentWindow(),
914 mxBorderWindow(),
915 maLocale(aLocale),
916 mnRole(nRole),
917 mnStateSet(0),
918 mbIsFocused(false),
919 mxParentAccessible(),
920 maChildren(),
921 maListeners()
922 {
923 }
924
925
926
927
LateInitialization(void)928 void PresenterAccessible::AccessibleObject::LateInitialization (void)
929 {
930 AccessibleFocusManager::Instance()->AddFocusableObject(this);
931 }
932
933
934
935
~AccessibleObject(void)936 PresenterAccessible::AccessibleObject::~AccessibleObject (void)
937 {
938 }
939
940
941
942
SetWindow(const Reference<awt::XWindow> & rxContentWindow,const Reference<awt::XWindow> & rxBorderWindow)943 void PresenterAccessible::AccessibleObject::SetWindow (
944 const Reference<awt::XWindow>& rxContentWindow,
945 const Reference<awt::XWindow>& rxBorderWindow)
946 {
947 Reference<awt::XWindow2> xContentWindow (rxContentWindow, UNO_QUERY);
948
949 if (mxContentWindow.get() != xContentWindow.get())
950 {
951 if (mxContentWindow.is())
952 {
953 mxContentWindow->removeWindowListener(this);
954 }
955
956 mxContentWindow = xContentWindow;
957 mxBorderWindow = Reference<awt::XWindow2>(rxBorderWindow, UNO_QUERY);
958
959 if (mxContentWindow.is())
960 {
961 mxContentWindow->addWindowListener(this);
962 }
963
964 UpdateStateSet();
965 }
966 }
967
968
969
970
SetAccessibleParent(const Reference<XAccessible> & rxAccessibleParent)971 void PresenterAccessible::AccessibleObject::SetAccessibleParent (
972 const Reference<XAccessible>& rxAccessibleParent)
973 {
974 mxParentAccessible = rxAccessibleParent;
975 }
976
977
978
979
disposing(void)980 void SAL_CALL PresenterAccessible::AccessibleObject::disposing (void)
981 {
982 AccessibleFocusManager::Instance()->RemoveFocusableObject(this);
983 SetWindow(NULL, NULL);
984 }
985
986
987
988
989 //----- XAccessible -------------------------------------------------------
990
991 Reference<XAccessibleContext> SAL_CALL
getAccessibleContext(void)992 PresenterAccessible::AccessibleObject::getAccessibleContext (void)
993 throw (RuntimeException)
994 {
995 ThrowIfDisposed();
996
997 return this;
998 }
999
1000
1001
1002
1003 //----- XAccessibleContext ----------------------------------------------
1004
getAccessibleChildCount(void)1005 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getAccessibleChildCount (void)
1006 throw (cssu::RuntimeException)
1007 {
1008 ThrowIfDisposed();
1009
1010 const sal_Int32 nChildCount (maChildren.size());
1011
1012 return nChildCount;
1013 }
1014
1015
1016
1017
1018 Reference<XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)1019 PresenterAccessible::AccessibleObject::getAccessibleChild (sal_Int32 nIndex)
1020 throw (lang::IndexOutOfBoundsException, RuntimeException)
1021 {
1022 ThrowIfDisposed();
1023
1024 if (nIndex<0 || nIndex>=sal_Int32(maChildren.size()))
1025 ThrowException("invalid child index", ET_IndexOutOfBounds);
1026
1027 return Reference<XAccessible>(maChildren[nIndex].get());
1028 }
1029
1030
1031
1032
1033 Reference<XAccessible> SAL_CALL
getAccessibleParent(void)1034 PresenterAccessible::AccessibleObject::getAccessibleParent (void)
1035 throw (RuntimeException)
1036 {
1037 ThrowIfDisposed();
1038
1039 return mxParentAccessible;
1040 }
1041
1042
1043
1044
1045 sal_Int32 SAL_CALL
getAccessibleIndexInParent(void)1046 PresenterAccessible::AccessibleObject::getAccessibleIndexInParent (void)
1047 throw (RuntimeException)
1048 {
1049 ThrowIfDisposed();
1050
1051 const Reference<XAccessible> xThis (this);
1052 if (mxParentAccessible.is())
1053 {
1054 const Reference<XAccessibleContext> xContext (mxParentAccessible->getAccessibleContext());
1055 for (sal_Int32 nIndex=0,nCount=xContext->getAccessibleChildCount();
1056 nIndex<nCount;
1057 ++nIndex)
1058 {
1059 if (xContext->getAccessibleChild(nIndex) == xThis)
1060 return nIndex;
1061 }
1062 }
1063
1064 return 0;
1065 }
1066
1067
1068
1069
1070 sal_Int16 SAL_CALL
getAccessibleRole(void)1071 PresenterAccessible::AccessibleObject::getAccessibleRole (void)
1072 throw (RuntimeException)
1073 {
1074 ThrowIfDisposed();
1075
1076 return mnRole;
1077 }
1078
1079
1080
1081
1082 OUString SAL_CALL
getAccessibleDescription(void)1083 PresenterAccessible::AccessibleObject::getAccessibleDescription (void)
1084 throw (RuntimeException)
1085 {
1086 ThrowIfDisposed();
1087
1088 return msName;
1089 }
1090
1091
1092
1093
1094 OUString SAL_CALL
getAccessibleName(void)1095 PresenterAccessible::AccessibleObject::getAccessibleName (void)
1096 throw (cssu::RuntimeException)
1097 {
1098 ThrowIfDisposed();
1099
1100 return msName;
1101 }
1102
1103
1104
1105
1106 Reference<XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)1107 PresenterAccessible::AccessibleObject::getAccessibleRelationSet (void)
1108 throw (RuntimeException)
1109 {
1110 ThrowIfDisposed();
1111
1112 return NULL;
1113 }
1114
1115
1116
1117
1118 Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)1119 PresenterAccessible::AccessibleObject::getAccessibleStateSet (void)
1120 throw (RuntimeException)
1121 {
1122 ThrowIfDisposed();
1123
1124 return Reference<XAccessibleStateSet>(new AccessibleStateSet(mnStateSet));
1125 }
1126
1127
1128
1129
1130 lang::Locale SAL_CALL
getLocale(void)1131 PresenterAccessible::AccessibleObject::getLocale (void)
1132 throw (RuntimeException,
1133 IllegalAccessibleComponentStateException)
1134 {
1135 ThrowIfDisposed();
1136
1137 if (mxParentAccessible.is())
1138 {
1139 Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext());
1140 if (xParentContext.is())
1141 return xParentContext->getLocale();
1142 }
1143 return maLocale;
1144 }
1145
1146
1147
1148
1149 //----- XAccessibleComponent ------------------------------------------------
1150
containsPoint(const awt::Point & rPoint)1151 sal_Bool SAL_CALL PresenterAccessible::AccessibleObject::containsPoint (
1152 const awt::Point& rPoint)
1153 throw (RuntimeException)
1154 {
1155 ThrowIfDisposed();
1156
1157 if (mxContentWindow.is())
1158 {
1159 const awt::Rectangle aBox (getBounds());
1160 return rPoint.X>=aBox.X
1161 && rPoint.Y>=aBox.Y
1162 && rPoint.X<aBox.X+aBox.Width
1163 && rPoint.Y<aBox.Y+aBox.Height;
1164 }
1165 else
1166 return false;
1167 }
1168
1169
1170
1171
1172 Reference<XAccessible> SAL_CALL
getAccessibleAtPoint(const awt::Point & rPoint)1173 PresenterAccessible::AccessibleObject::getAccessibleAtPoint (const awt::Point& rPoint)
1174 throw (RuntimeException)
1175 {
1176 (void)rPoint;
1177 ThrowIfDisposed();
1178
1179 return Reference<XAccessible>();
1180 }
1181
1182
1183
1184
getBounds(void)1185 awt::Rectangle SAL_CALL PresenterAccessible::AccessibleObject::getBounds (void)
1186 throw (RuntimeException)
1187 {
1188 ThrowIfDisposed();
1189
1190 awt::Rectangle aBox;
1191
1192 const awt::Point aLocation (GetRelativeLocation());
1193 const awt::Size aSize (GetSize());
1194
1195 return awt::Rectangle (aLocation.X, aLocation.Y, aSize.Width, aSize.Height);
1196 }
1197
1198
1199
1200
getLocation(void)1201 awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocation (void)
1202 throw (RuntimeException)
1203 {
1204 ThrowIfDisposed();
1205
1206 const awt::Point aLocation (GetRelativeLocation());
1207
1208 return aLocation;
1209 }
1210
1211
1212
1213
getLocationOnScreen(void)1214 awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocationOnScreen (void)
1215 throw (RuntimeException)
1216 {
1217 ThrowIfDisposed();
1218
1219 awt::Point aRelativeLocation (GetRelativeLocation());
1220 awt::Point aParentLocationOnScreen (GetAbsoluteParentLocation());
1221
1222 return awt::Point(
1223 aRelativeLocation.X + aParentLocationOnScreen.X,
1224 aRelativeLocation.Y + aParentLocationOnScreen.Y);
1225 }
1226
1227
1228
1229
getSize(void)1230 awt::Size SAL_CALL PresenterAccessible::AccessibleObject::getSize (void)
1231 throw (RuntimeException)
1232 {
1233 ThrowIfDisposed();
1234
1235 const awt::Size aSize (GetSize());
1236
1237 return aSize;
1238 }
1239
1240
1241
1242
grabFocus(void)1243 void SAL_CALL PresenterAccessible::AccessibleObject::grabFocus (void)
1244 throw (RuntimeException)
1245 {
1246 ThrowIfDisposed();
1247 if (mxBorderWindow.is())
1248 mxBorderWindow->setFocus();
1249 else if (mxContentWindow.is())
1250 mxContentWindow->setFocus();
1251 }
1252
1253
1254
1255
getForeground(void)1256 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getForeground (void)
1257 throw (RuntimeException)
1258 {
1259 ThrowIfDisposed();
1260
1261 return 0x00ffffff;
1262 }
1263
1264
1265
1266
getBackground(void)1267 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getBackground (void)
1268 throw (RuntimeException)
1269 {
1270 ThrowIfDisposed();
1271
1272 return 0x00000000;
1273 }
1274
1275
1276
1277
1278 //----- XAccessibleEventBroadcaster -------------------------------------------
1279
addEventListener(const Reference<XAccessibleEventListener> & rxListener)1280 void SAL_CALL PresenterAccessible::AccessibleObject::addEventListener (
1281 const Reference<XAccessibleEventListener>& rxListener)
1282 throw (RuntimeException)
1283 {
1284 if (rxListener.is())
1285 {
1286 const osl::MutexGuard aGuard(m_aMutex);
1287
1288 if (IsDisposed())
1289 {
1290 uno::Reference<uno::XInterface> xThis (static_cast<XWeak*>(this), UNO_QUERY);
1291 rxListener->disposing (lang::EventObject(xThis));
1292 }
1293 else
1294 {
1295 maListeners.push_back(rxListener);
1296 }
1297 }
1298 }
1299
1300
1301
1302
removeEventListener(const Reference<XAccessibleEventListener> & rxListener)1303 void SAL_CALL PresenterAccessible::AccessibleObject::removeEventListener (
1304 const Reference<XAccessibleEventListener>& rxListener)
1305 throw (RuntimeException)
1306 {
1307 ThrowIfDisposed();
1308 if (rxListener.is())
1309 {
1310 const osl::MutexGuard aGuard(m_aMutex);
1311
1312 maListeners.erase(std::remove(maListeners.begin(), maListeners.end(), rxListener));
1313 }
1314 }
1315
1316
1317
1318
1319 //----- XWindowListener ---------------------------------------------------
1320
windowResized(const css::awt::WindowEvent & rEvent)1321 void SAL_CALL PresenterAccessible::AccessibleObject::windowResized (
1322 const css::awt::WindowEvent& rEvent)
1323 throw (cssu::RuntimeException)
1324 {
1325 (void)rEvent;
1326
1327 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any());
1328 }
1329
1330
1331
1332
windowMoved(const css::awt::WindowEvent & rEvent)1333 void SAL_CALL PresenterAccessible::AccessibleObject::windowMoved (
1334 const css::awt::WindowEvent& rEvent)
1335 throw (cssu::RuntimeException)
1336 {
1337 (void)rEvent;
1338
1339 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any());
1340 }
1341
1342
1343
1344
windowShown(const css::lang::EventObject & rEvent)1345 void SAL_CALL PresenterAccessible::AccessibleObject::windowShown (
1346 const css::lang::EventObject& rEvent)
1347 throw (cssu::RuntimeException)
1348 {
1349 (void)rEvent;
1350 UpdateStateSet();
1351 }
1352
1353
1354
1355
windowHidden(const css::lang::EventObject & rEvent)1356 void SAL_CALL PresenterAccessible::AccessibleObject::windowHidden (
1357 const css::lang::EventObject& rEvent)
1358 throw (cssu::RuntimeException)
1359 {
1360 (void)rEvent;
1361 UpdateStateSet();
1362 }
1363
1364
1365
1366
1367 //----- XEventListener --------------------------------------------------------
1368
disposing(const css::lang::EventObject & rEvent)1369 void SAL_CALL PresenterAccessible::AccessibleObject::disposing (const css::lang::EventObject& rEvent)
1370 throw (cssu::RuntimeException)
1371 {
1372 if (rEvent.Source == mxContentWindow)
1373 {
1374 mxContentWindow = NULL;
1375 mxBorderWindow = NULL;
1376 }
1377 else
1378 {
1379 SetWindow(NULL, NULL);
1380 }
1381 }
1382
1383
1384
1385
1386 //----- private ---------------------------------------------------------------
1387
GetWindowState(const sal_Int16 nType) const1388 bool PresenterAccessible::AccessibleObject::GetWindowState (const sal_Int16 nType) const
1389 {
1390 switch (nType)
1391 {
1392 case AccessibleStateType::ENABLED:
1393 return mxContentWindow.is() && mxContentWindow->isEnabled();
1394
1395 case AccessibleStateType::FOCUSABLE:
1396 return true;
1397
1398 case AccessibleStateType::FOCUSED:
1399 return mbIsFocused;
1400
1401 case AccessibleStateType::SHOWING:
1402 return mxContentWindow.is() && mxContentWindow->isVisible();
1403
1404 default:
1405 return false;
1406 }
1407 }
1408
1409
1410
1411
UpdateStateSet(void)1412 void PresenterAccessible::AccessibleObject::UpdateStateSet (void)
1413 {
1414 UpdateState(AccessibleStateType::FOCUSABLE, true);
1415 UpdateState(AccessibleStateType::VISIBLE, true);
1416 UpdateState(AccessibleStateType::ENABLED, true);
1417 UpdateState(AccessibleStateType::MULTI_LINE, true);
1418 UpdateState(AccessibleStateType::SENSITIVE, true);
1419
1420 UpdateState(AccessibleStateType::ENABLED, GetWindowState(AccessibleStateType::ENABLED));
1421 UpdateState(AccessibleStateType::FOCUSED, GetWindowState(AccessibleStateType::FOCUSED));
1422 UpdateState(AccessibleStateType::SHOWING, GetWindowState(AccessibleStateType::SHOWING));
1423 // UpdateState(AccessibleStateType::ACTIVE, GetWindowState(AccessibleStateType::ACTIVE));
1424 }
1425
1426
1427
1428
UpdateState(const sal_Int16 nState,const bool bValue)1429 void PresenterAccessible::AccessibleObject::UpdateState(
1430 const sal_Int16 nState,
1431 const bool bValue)
1432 {
1433 const sal_uInt32 nStateMask (AccessibleStateSet::GetStateMask(nState));
1434 if (((mnStateSet & nStateMask)!=0) != bValue)
1435 {
1436 if (bValue)
1437 {
1438 mnStateSet |= nStateMask;
1439 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(), Any(nState));
1440 }
1441 else
1442 {
1443 mnStateSet &= ~nStateMask;
1444 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(nState), Any());
1445 }
1446 }
1447 }
1448
1449
1450
1451
AddChild(const::rtl::Reference<AccessibleObject> & rpChild)1452 void PresenterAccessible::AccessibleObject::AddChild (
1453 const ::rtl::Reference<AccessibleObject>& rpChild)
1454 {
1455 maChildren.push_back(rpChild);
1456 rpChild->SetAccessibleParent(this);
1457 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
1458 }
1459
1460
1461
1462
RemoveChild(const::rtl::Reference<AccessibleObject> & rpChild)1463 void PresenterAccessible::AccessibleObject::RemoveChild (
1464 const ::rtl::Reference<AccessibleObject>& rpChild)
1465 {
1466 rpChild->SetAccessibleParent(Reference<XAccessible>());
1467 maChildren.erase(::std::find(maChildren.begin(), maChildren.end(), rpChild));
1468 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
1469 }
1470
1471
1472
1473
SetIsFocused(const bool bIsFocused)1474 void PresenterAccessible::AccessibleObject::SetIsFocused (const bool bIsFocused)
1475 {
1476 if (mbIsFocused != bIsFocused)
1477 {
1478 mbIsFocused = bIsFocused;
1479 UpdateStateSet();
1480 }
1481 }
1482
1483
1484
1485
SetAccessibleName(const::rtl::OUString & rsName)1486 void PresenterAccessible::AccessibleObject::SetAccessibleName (const ::rtl::OUString& rsName)
1487 {
1488 if (msName != rsName)
1489 {
1490 const OUString sOldName(msName);
1491 msName = rsName;
1492 FireAccessibleEvent(AccessibleEventId::NAME_CHANGED, Any(sOldName), Any(msName));
1493 }
1494 }
1495
1496
1497
1498
FireAccessibleEvent(const sal_Int16 nEventId,const uno::Any & rOldValue,const uno::Any & rNewValue)1499 void PresenterAccessible::AccessibleObject::FireAccessibleEvent (
1500 const sal_Int16 nEventId,
1501 const uno::Any& rOldValue,
1502 const uno::Any& rNewValue )
1503 {
1504 AccessibleEventObject aEventObject;
1505
1506 aEventObject.Source = Reference<XWeak>(this);
1507 aEventObject.EventId = nEventId;
1508 aEventObject.NewValue = rNewValue;
1509 aEventObject.OldValue = rOldValue;
1510
1511 ::std::vector<Reference<XAccessibleEventListener> > aListenerCopy(maListeners);
1512 for (::std::vector<Reference<XAccessibleEventListener> >::const_iterator
1513 iListener(aListenerCopy.begin()),
1514 iEnd(aListenerCopy.end());
1515 iListener!=iEnd;
1516 ++iListener)
1517 {
1518 try
1519 {
1520 (*iListener)->notifyEvent(aEventObject);
1521 }
1522 catch(lang::DisposedException&)
1523 {
1524 // Listener has been disposed and should have been removed
1525 // already.
1526 removeEventListener(*iListener);
1527 }
1528 catch(Exception&)
1529 {
1530 // Ignore all other exceptions and assume that they are
1531 // caused by a temporary problem.
1532 }
1533 }
1534 }
1535
1536
1537
GetRelativeLocation(void)1538 awt::Point PresenterAccessible::AccessibleObject::GetRelativeLocation (void)
1539 {
1540 awt::Point aLocation;
1541 if (mxContentWindow.is())
1542 {
1543 const awt::Rectangle aContentBox (mxContentWindow->getPosSize());
1544 aLocation.X = aContentBox.X;
1545 aLocation.Y = aContentBox.Y;
1546 if (mxBorderWindow.is())
1547 {
1548 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
1549 aLocation.X += aBorderBox.X;
1550 aLocation.Y += aBorderBox.Y;
1551 }
1552 }
1553 return aLocation;
1554 }
1555
1556
1557
1558
GetSize(void)1559 awt::Size PresenterAccessible::AccessibleObject::GetSize (void)
1560 {
1561 if (mxContentWindow.is())
1562 {
1563 const awt::Rectangle aBox (mxContentWindow->getPosSize());
1564 return awt::Size(aBox.Width, aBox.Height);
1565 }
1566 else
1567 return awt::Size();
1568 }
1569
1570
1571
1572
GetAbsoluteParentLocation(void)1573 awt::Point PresenterAccessible::AccessibleObject::GetAbsoluteParentLocation (void)
1574 {
1575 Reference<XAccessibleComponent> xParentComponent;
1576 if (mxParentAccessible.is())
1577 xParentComponent = Reference<XAccessibleComponent>(
1578 mxParentAccessible->getAccessibleContext(), UNO_QUERY);
1579 if (xParentComponent.is())
1580 return xParentComponent->getLocationOnScreen();
1581 else
1582 return awt::Point();
1583 }
1584
1585
1586
1587
IsDisposed(void) const1588 sal_Bool PresenterAccessible::AccessibleObject::IsDisposed (void) const
1589 {
1590 return (rBHelper.bDisposed || rBHelper.bInDispose);
1591 }
1592
1593
1594
1595
ThrowIfDisposed(void) const1596 void PresenterAccessible::AccessibleObject::ThrowIfDisposed (void) const
1597 throw (lang::DisposedException)
1598 {
1599 if (rBHelper.bDisposed || rBHelper.bInDispose)
1600 ThrowException("object has already been disposed", ET_Disposed);
1601 }
1602
1603
1604
1605
ThrowException(const sal_Char * pMessage,const ExceptionType eExceptionType) const1606 void PresenterAccessible::AccessibleObject::ThrowException (
1607 const sal_Char* pMessage,
1608 const ExceptionType eExceptionType) const
1609 {
1610 const OUString sMessage (OUString(A2S("PresenterAccessible: ")) + OUString(A2S(pMessage)));
1611 const Reference<XInterface> xObject (
1612 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1613 switch (eExceptionType)
1614 {
1615 default:
1616 case ET_Runtime:
1617 throw RuntimeException(sMessage, xObject);
1618 case ET_Disposed:
1619 throw lang::DisposedException(sMessage, xObject);
1620 case ET_IndexOutOfBounds:
1621 throw lang::IndexOutOfBoundsException(sMessage, xObject);
1622 }
1623 }
1624
1625
1626
1627
1628
1629 //===== AccessibleStateSet ====================================================
1630
AccessibleStateSet(const sal_Int32 nStateSet)1631 AccessibleStateSet::AccessibleStateSet (const sal_Int32 nStateSet)
1632 : AccessibleStateSetInterfaceBase(m_aMutex),
1633 mnStateSet (nStateSet)
1634 {
1635 }
1636
1637
1638
1639
~AccessibleStateSet(void)1640 AccessibleStateSet::~AccessibleStateSet (void)
1641 {
1642 }
1643
1644
1645
1646
GetStateMask(const sal_Int16 nState)1647 sal_uInt32 AccessibleStateSet::GetStateMask (const sal_Int16 nState)
1648 {
1649 if (nState<0 || nState>=sal_Int16(sizeof(sal_uInt32)*8))
1650 {
1651 throw RuntimeException(A2S("AccessibleStateSet::GetStateMask: invalid state"), NULL);
1652 }
1653
1654 return 1<<nState;
1655 }
1656
1657
1658
1659
1660 //----- XAccessibleStateSet ---------------------------------------------------
1661
isEmpty(void)1662 sal_Bool SAL_CALL AccessibleStateSet::isEmpty (void)
1663 throw (cssu::RuntimeException)
1664 {
1665 return mnStateSet==0;
1666 }
1667
1668
1669
1670
contains(sal_Int16 nState)1671 sal_Bool SAL_CALL AccessibleStateSet::contains (sal_Int16 nState)
1672 throw (cssu::RuntimeException)
1673 {
1674 return (mnStateSet & GetStateMask(nState)) != 0;
1675 }
1676
1677
1678
1679
containsAll(const cssu::Sequence<sal_Int16> & rStateSet)1680 sal_Bool SAL_CALL AccessibleStateSet::containsAll (const cssu::Sequence<sal_Int16>& rStateSet)
1681 throw (cssu::RuntimeException)
1682 {
1683 for (sal_Int32 nIndex=0,nCount=rStateSet.getLength(); nIndex<nCount; ++nIndex)
1684 {
1685 if ((mnStateSet & GetStateMask(rStateSet[nIndex])) == 0)
1686 return sal_False;
1687 }
1688 return sal_True;
1689 }
1690
1691
1692
1693
getStates(void)1694 cssu::Sequence<sal_Int16> SAL_CALL AccessibleStateSet::getStates (void)
1695 throw (cssu::RuntimeException)
1696 {
1697 ::std::vector<sal_Int16> aStates;
1698 aStates.reserve(sizeof(mnStateSet)*8);
1699 for (sal_uInt16 nIndex=0; nIndex<sizeof(mnStateSet)*8; ++nIndex)
1700 if ((mnStateSet & GetStateMask(nIndex)) != 0)
1701 aStates.push_back(nIndex);
1702 return Sequence<sal_Int16>(&aStates.front(), aStates.size());
1703 }
1704
1705
1706
1707
1708 //===== AccessibleRelationSet =================================================
1709
AccessibleRelationSet(void)1710 AccessibleRelationSet::AccessibleRelationSet (void)
1711 : AccessibleRelationSetInterfaceBase(m_aMutex),
1712 maRelations()
1713 {
1714 }
1715
1716
1717
1718
~AccessibleRelationSet(void)1719 AccessibleRelationSet::~AccessibleRelationSet (void)
1720 {
1721 }
1722
1723
1724
1725
AddRelation(const sal_Int16 nRelationType,const Reference<XInterface> & rxObject)1726 void AccessibleRelationSet::AddRelation (
1727 const sal_Int16 nRelationType,
1728 const Reference<XInterface>& rxObject)
1729 {
1730 maRelations.resize(maRelations.size()+1);
1731 maRelations.back().RelationType = nRelationType;
1732 maRelations.back().TargetSet.realloc(1);
1733 maRelations.back().TargetSet[0] = rxObject;
1734 }
1735
1736
1737
1738
1739 //----- XAccessibleRelationSet ------------------------------------------------
1740
getRelationCount(void)1741 sal_Int32 SAL_CALL AccessibleRelationSet::getRelationCount (void)
1742 throw (cssu::RuntimeException)
1743 {
1744 return maRelations.size();
1745 }
1746
1747
1748
1749
getRelation(sal_Int32 nIndex)1750 AccessibleRelation SAL_CALL AccessibleRelationSet::getRelation (sal_Int32 nIndex)
1751 throw (cssu::RuntimeException, css::lang::IndexOutOfBoundsException)
1752 {
1753 if (nIndex<0 && sal_uInt32(nIndex)>=maRelations.size())
1754 return AccessibleRelation();
1755 else
1756 return maRelations[nIndex];
1757 }
1758
1759
1760
1761
containsRelation(sal_Int16 nRelationType)1762 sal_Bool SAL_CALL AccessibleRelationSet::containsRelation (sal_Int16 nRelationType)
1763 throw (cssu::RuntimeException)
1764 {
1765 for (::std::vector<AccessibleRelation>::const_iterator iRelation(maRelations.begin());
1766 iRelation!=maRelations.end();
1767 ++iRelation)
1768 {
1769 if (iRelation->RelationType == nRelationType)
1770 return sal_True;
1771 }
1772 return sal_False;
1773 }
1774
1775
1776
1777
getRelationByType(sal_Int16 nRelationType)1778 AccessibleRelation SAL_CALL AccessibleRelationSet::getRelationByType (sal_Int16 nRelationType)
1779 throw (cssu::RuntimeException)
1780 {
1781 for (::std::vector<AccessibleRelation>::const_iterator iRelation(maRelations.begin());
1782 iRelation!=maRelations.end();
1783 ++iRelation)
1784 {
1785 if (iRelation->RelationType == nRelationType)
1786 return *iRelation;
1787 }
1788 return AccessibleRelation();
1789 }
1790
1791
1792
1793
1794 //===== PresenterAccessible::AccessibleParagraph ==============================
1795
AccessibleParagraph(const lang::Locale aLocale,const sal_Int16 nRole,const OUString & rsName,const SharedPresenterTextParagraph & rpParagraph,const sal_Int32 nParagraphIndex)1796 PresenterAccessible::AccessibleParagraph::AccessibleParagraph (
1797 const lang::Locale aLocale,
1798 const sal_Int16 nRole,
1799 const OUString& rsName,
1800 const SharedPresenterTextParagraph& rpParagraph,
1801 const sal_Int32 nParagraphIndex)
1802 : PresenterAccessibleParagraphInterfaceBase(aLocale, nRole, rsName),
1803 mpParagraph(rpParagraph),
1804 mnParagraphIndex(nParagraphIndex)
1805 {
1806 }
1807
1808
1809
1810
~AccessibleParagraph(void)1811 PresenterAccessible::AccessibleParagraph::~AccessibleParagraph (void)
1812 {
1813 }
1814
1815
1816
1817
1818 //----- XAccessibleContext ----------------------------------------------------
1819
1820 Reference<XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)1821 PresenterAccessible::AccessibleParagraph::getAccessibleRelationSet (void)
1822 throw (RuntimeException)
1823 {
1824 ThrowIfDisposed();
1825
1826 rtl::Reference<AccessibleRelationSet> pSet (new AccessibleRelationSet);
1827
1828 if (mxParentAccessible.is())
1829 {
1830 Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext());
1831 if (xParentContext.is())
1832 {
1833 if (mnParagraphIndex>0)
1834 pSet->AddRelation(
1835 AccessibleRelationType::CONTENT_FLOWS_FROM,
1836 xParentContext->getAccessibleChild(mnParagraphIndex-1));
1837
1838 if (mnParagraphIndex<xParentContext->getAccessibleChildCount()-1)
1839 pSet->AddRelation(
1840 AccessibleRelationType::CONTENT_FLOWS_TO,
1841 xParentContext->getAccessibleChild(mnParagraphIndex+1));
1842 }
1843 }
1844
1845 return Reference<XAccessibleRelationSet>(pSet.get());
1846 }
1847
1848
1849
1850
1851
1852
1853 //----- XAccessibleText -------------------------------------------------------
1854
getCaretPosition(void)1855 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCaretPosition (void)
1856 throw (cssu::RuntimeException)
1857 {
1858 ThrowIfDisposed();
1859
1860 sal_Int32 nPosition (-1);
1861 if (mpParagraph)
1862 nPosition = mpParagraph->GetCaretPosition();
1863
1864 return nPosition;
1865 }
1866
1867
1868
1869
setCaretPosition(sal_Int32 nIndex)1870 sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setCaretPosition (sal_Int32 nIndex)
1871 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException)
1872 {
1873 ThrowIfDisposed();
1874
1875 if (mpParagraph)
1876 {
1877 mpParagraph->SetCaretPosition(nIndex);
1878 return sal_True;
1879 }
1880 else
1881 return sal_False;
1882 }
1883
1884
1885
1886
getCharacter(sal_Int32 nIndex)1887 sal_Unicode SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacter (sal_Int32 nIndex)
1888 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException)
1889 {
1890 ThrowIfDisposed();
1891
1892 if (mpParagraph)
1893 return mpParagraph->GetCharacter(nIndex);
1894 else
1895 {
1896 ThrowException("no text support in current mode", ET_IndexOutOfBounds);
1897 // The method above throws an exception and the following line is
1898 // never reached. But there is at least one compiler that can not
1899 // detect this and we need the return to make it happy.
1900 return sal_Unicode();
1901 }
1902 }
1903
1904
1905
1906
1907 Sequence<css::beans::PropertyValue> SAL_CALL
getCharacterAttributes(::sal_Int32 nIndex,const cssu::Sequence<rtl::OUString> & rRequestedAttributes)1908 PresenterAccessible::AccessibleParagraph::getCharacterAttributes (
1909 ::sal_Int32 nIndex,
1910 const cssu::Sequence<rtl::OUString>& rRequestedAttributes)
1911 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
1912 {
1913 ThrowIfDisposed();
1914
1915 #ifdef VERBOSE
1916 OSL_TRACE("PresenterAccessible::AccessibleParagraph::getCharacterAttributes at %x,%d returns empty set\r",
1917 this,nIndex);
1918 for (sal_Int32 nAttributeIndex(0),nAttributeCount(rRequestedAttributes.getLength());
1919 nAttributeIndex<nAttributeCount;
1920 ++nAttributeIndex)
1921 {
1922 OSL_TRACE(" requested attribute %d is %s\r",
1923 nAttributeIndex,
1924 OUStringToOString(rRequestedAttributes[nAttributeIndex], RTL_TEXTENCODING_UTF8).getStr());
1925 }
1926 #endif
1927
1928 // Character properties are not supported.
1929 (void)nIndex;
1930 (void)rRequestedAttributes;
1931 return Sequence<css::beans::PropertyValue>();
1932 }
1933
1934
1935
1936
getCharacterBounds(sal_Int32 nIndex)1937 awt::Rectangle SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterBounds (
1938 sal_Int32 nIndex)
1939 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
1940 {
1941 ThrowIfDisposed();
1942
1943 awt::Rectangle aCharacterBox;
1944 if (nIndex < 0)
1945 {
1946 ThrowException("invalid text index", ET_IndexOutOfBounds);
1947 }
1948 else if (mpParagraph)
1949 {
1950 aCharacterBox = mpParagraph->GetCharacterBounds(nIndex, false);
1951 // Convert coordinates relative to the window origin into absolute
1952 // screen coordinates.
1953 const awt::Point aWindowLocationOnScreen (getLocationOnScreen());
1954 aCharacterBox.X += aWindowLocationOnScreen.X;
1955 aCharacterBox.Y += aWindowLocationOnScreen.Y;
1956 }
1957 else
1958 {
1959 ThrowException("no text support in current mode", ET_IndexOutOfBounds);
1960 }
1961
1962 return aCharacterBox;
1963 }
1964
1965
1966
1967
getCharacterCount(void)1968 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterCount (void)
1969 throw (cssu::RuntimeException)
1970 {
1971 ThrowIfDisposed();
1972
1973 sal_Int32 nCount (0);
1974 if (mpParagraph)
1975 nCount = mpParagraph->GetCharacterCount();
1976
1977 return nCount;
1978 }
1979
1980
1981
1982
getIndexAtPoint(const css::awt::Point & rPoint)1983 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getIndexAtPoint (
1984 const css::awt::Point& rPoint)
1985 throw (cssu::RuntimeException)
1986 {
1987 ThrowIfDisposed();
1988
1989 sal_Int32 nIndex (-1);
1990 if (mpParagraph)
1991 nIndex = mpParagraph->GetIndexAtPoint(rPoint);
1992
1993 return nIndex;
1994 }
1995
1996
1997
1998
getSelectedText(void)1999 ::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectedText (void)
2000 throw (cssu::RuntimeException)
2001 {
2002 ThrowIfDisposed();
2003
2004 return getTextRange(getSelectionStart(), getSelectionEnd());
2005 }
2006
2007
2008
2009
getSelectionStart(void)2010 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionStart (void)
2011 throw (cssu::RuntimeException)
2012 {
2013 ThrowIfDisposed();
2014
2015 return getCaretPosition();
2016 }
2017
2018
2019
2020
getSelectionEnd(void)2021 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionEnd (void)
2022 throw (cssu::RuntimeException)
2023 {
2024 ThrowIfDisposed();
2025
2026 return getCaretPosition();
2027 }
2028
2029
2030
2031
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2032 sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setSelection (
2033 sal_Int32 nStartIndex,
2034 sal_Int32 nEndIndex)
2035 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
2036 {
2037 (void)nEndIndex;
2038 ThrowIfDisposed();
2039
2040 return setCaretPosition(nStartIndex);
2041 }
2042
2043
2044
2045
getText(void)2046 ::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getText (void)
2047 throw (cssu::RuntimeException)
2048 {
2049 ThrowIfDisposed();
2050
2051 ::rtl::OUString sText;
2052 if (mpParagraph)
2053 sText = mpParagraph->GetText();
2054
2055 return sText;
2056 }
2057
2058
2059
2060
getTextRange(sal_Int32 nLocalStartIndex,sal_Int32 nLocalEndIndex)2061 ::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getTextRange (
2062 sal_Int32 nLocalStartIndex,
2063 sal_Int32 nLocalEndIndex)
2064 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
2065 {
2066 ThrowIfDisposed();
2067
2068 ::rtl::OUString sText;
2069 if (mpParagraph)
2070 {
2071 const TextSegment aSegment (
2072 mpParagraph->CreateTextSegment(nLocalStartIndex, nLocalEndIndex));
2073 sText = aSegment.SegmentText;
2074 }
2075
2076 return sText;
2077 }
2078
2079
2080
2081
getTextAtIndex(sal_Int32 nLocalCharacterIndex,sal_Int16 nTextType)2082 TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextAtIndex (
2083 sal_Int32 nLocalCharacterIndex,
2084 sal_Int16 nTextType)
2085 throw (css::lang::IndexOutOfBoundsException,
2086 css::lang::IllegalArgumentException,
2087 cssu::RuntimeException)
2088 {
2089 ThrowIfDisposed();
2090
2091 TextSegment aSegment;
2092 if (mpParagraph)
2093 aSegment = mpParagraph->GetTextSegment(0, nLocalCharacterIndex, nTextType);
2094
2095 return aSegment;
2096 }
2097
2098
2099
2100
getTextBeforeIndex(sal_Int32 nLocalCharacterIndex,sal_Int16 nTextType)2101 TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBeforeIndex (
2102 sal_Int32 nLocalCharacterIndex,
2103 sal_Int16 nTextType)
2104 throw (css::lang::IndexOutOfBoundsException,
2105 css::lang::IllegalArgumentException,
2106 cssu::RuntimeException)
2107 {
2108 ThrowIfDisposed();
2109
2110 TextSegment aSegment;
2111 if (mpParagraph)
2112 aSegment = mpParagraph->GetTextSegment(-1, nLocalCharacterIndex, nTextType);
2113
2114 return aSegment;
2115 }
2116
2117
2118
2119
getTextBehindIndex(sal_Int32 nLocalCharacterIndex,sal_Int16 nTextType)2120 TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBehindIndex (
2121 sal_Int32 nLocalCharacterIndex,
2122 sal_Int16 nTextType)
2123 throw (css::lang::IndexOutOfBoundsException,
2124 css::lang::IllegalArgumentException,
2125 cssu::RuntimeException)
2126 {
2127 ThrowIfDisposed();
2128
2129 TextSegment aSegment;
2130 if (mpParagraph)
2131 aSegment = mpParagraph->GetTextSegment(+1, nLocalCharacterIndex, nTextType);
2132
2133 return aSegment;
2134 }
2135
2136
2137
2138
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2139 sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::copyText (
2140 sal_Int32 nStartIndex,
2141 sal_Int32 nEndIndex)
2142 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
2143 {
2144 ThrowIfDisposed();
2145
2146 // Return false because copying to clipboard is not supported.
2147 // It IS supported in the notes view. There is no need to duplicate
2148 // this here.
2149 (void)nStartIndex;
2150 (void)nEndIndex;
2151 return sal_False;
2152 }
2153
2154
2155
2156
2157 //----- protected -------------------------------------------------------------
2158
GetRelativeLocation(void)2159 awt::Point PresenterAccessible::AccessibleParagraph::GetRelativeLocation (void)
2160 {
2161 awt::Point aLocation (AccessibleObject::GetRelativeLocation());
2162 if (mpParagraph)
2163 {
2164 const awt::Point aParagraphLocation (mpParagraph->GetRelativeLocation());
2165 aLocation.X += aParagraphLocation.X;
2166 aLocation.Y += aParagraphLocation.Y;
2167 }
2168
2169 return aLocation;
2170 }
2171
2172
2173
2174
GetSize(void)2175 awt::Size PresenterAccessible::AccessibleParagraph::GetSize (void)
2176 {
2177 if (mpParagraph)
2178 return mpParagraph->GetSize();
2179 else
2180 return AccessibleObject::GetSize();
2181 }
2182
2183
2184
2185
GetAbsoluteParentLocation(void)2186 awt::Point PresenterAccessible::AccessibleParagraph::GetAbsoluteParentLocation (void)
2187 {
2188 if (mxParentAccessible.is())
2189 {
2190 Reference<XAccessibleContext> xParentContext(
2191 mxParentAccessible->getAccessibleContext(), UNO_QUERY);
2192 if (xParentContext.is())
2193 {
2194 Reference<XAccessibleComponent> xGrandParentComponent(
2195 xParentContext->getAccessibleParent(), UNO_QUERY);
2196 if (xGrandParentComponent.is())
2197 return xGrandParentComponent->getLocationOnScreen();
2198 }
2199 }
2200
2201 return awt::Point();
2202 }
2203
2204
2205
2206
GetWindowState(const sal_Int16 nType) const2207 bool PresenterAccessible::AccessibleParagraph::GetWindowState (const sal_Int16 nType) const
2208 {
2209 switch (nType)
2210 {
2211 case AccessibleStateType::EDITABLE:
2212 return mpParagraph.get()!=NULL;
2213
2214 case AccessibleStateType::ACTIVE:
2215 return true;
2216
2217 default:
2218 return AccessibleObject::GetWindowState(nType);
2219 }
2220 }
2221
2222
2223
2224
2225
2226
2227 //===== AccessibleNotes =======================================================
2228
AccessibleNotes(const css::lang::Locale aLocale,const sal_Int16 nRole,const::rtl::OUString & rsName)2229 AccessibleNotes::AccessibleNotes (
2230 const css::lang::Locale aLocale,
2231 const sal_Int16 nRole,
2232 const ::rtl::OUString& rsName)
2233 : AccessibleObject(aLocale,nRole,rsName),
2234 mpTextView()
2235 {
2236 }
2237
2238
2239
2240
Create(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const lang::Locale aLocale,const Reference<awt::XWindow> & rxContentWindow,const Reference<awt::XWindow> & rxBorderWindow,const::boost::shared_ptr<PresenterTextView> & rpTextView)2241 rtl::Reference<PresenterAccessible::AccessibleObject> AccessibleNotes::Create (
2242 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
2243 const lang::Locale aLocale,
2244 const Reference<awt::XWindow>& rxContentWindow,
2245 const Reference<awt::XWindow>& rxBorderWindow,
2246 const ::boost::shared_ptr<PresenterTextView>& rpTextView)
2247 {
2248 OUString sName (A2S("Presenter Notes Text"));
2249 {
2250 PresenterConfigurationAccess aConfiguration (
2251 rxContext,
2252 OUString::createFromAscii("/org.openoffice.Office.PresenterScreen/"),
2253 PresenterConfigurationAccess::READ_ONLY);
2254 aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Notes/String"))
2255 >>= sName;
2256 }
2257
2258 rtl::Reference<AccessibleNotes> pObject (
2259 new AccessibleNotes(
2260 aLocale,
2261 AccessibleRole::PANEL,
2262 sName));
2263 pObject->LateInitialization();
2264 pObject->SetTextView(rpTextView);
2265 pObject->UpdateStateSet();
2266 pObject->SetWindow(rxContentWindow, rxBorderWindow);
2267
2268 return rtl::Reference<PresenterAccessible::AccessibleObject>(pObject.get());
2269 }
2270
2271
2272
2273
SetTextView(const::boost::shared_ptr<PresenterTextView> & rpTextView)2274 void AccessibleNotes::SetTextView (
2275 const ::boost::shared_ptr<PresenterTextView>& rpTextView)
2276 {
2277 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > aChildren;
2278
2279 // Release any listeners to the current text view.
2280 if (mpTextView)
2281 {
2282 mpTextView->GetCaret()->SetCaretMotionBroadcaster(
2283 ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>());
2284 mpTextView->SetTextChangeBroadcaster(
2285 ::boost::function<void(void)>());
2286 }
2287
2288 mpTextView = rpTextView;
2289
2290 if (mpTextView)
2291 {
2292 // Create a new set of children, one for each paragraph.
2293 const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount());
2294 for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex)
2295 {
2296 rtl::Reference<PresenterAccessible::AccessibleParagraph> pParagraph (
2297 new PresenterAccessible::AccessibleParagraph(
2298 css::lang::Locale(),
2299 AccessibleRole::PARAGRAPH,
2300 A2S("Paragraph")+OUString::valueOf(nIndex),
2301 rpTextView->GetParagraph(nIndex),
2302 nIndex));
2303 pParagraph->LateInitialization();
2304 pParagraph->SetWindow(
2305 Reference<awt::XWindow>(mxContentWindow, UNO_QUERY),
2306 Reference<awt::XWindow>(mxBorderWindow, UNO_QUERY));
2307 pParagraph->SetAccessibleParent(this);
2308 aChildren.push_back(
2309 rtl::Reference<PresenterAccessible::AccessibleObject>(pParagraph.get()));
2310 }
2311 maChildren.swap(aChildren);
2312 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
2313
2314 // Dispose the old children. (This will remove them from the focus
2315 // manager).
2316 for (std::vector<rtl::Reference<AccessibleObject> >::const_iterator
2317 iChild(aChildren.begin()), iEnd(aChildren.end());
2318 iChild!=iEnd;
2319 ++iChild)
2320 {
2321 Reference<lang::XComponent> xComponent (static_cast<XWeak*>(iChild->get()), UNO_QUERY);
2322 if (xComponent.is())
2323 xComponent->dispose();
2324 }
2325
2326 // This class acts as a controller of who broadcasts caret motion
2327 // events and handles text changes. Register the corresponding
2328 // listeners here.
2329 mpTextView->GetCaret()->SetCaretMotionBroadcaster(
2330 ::boost::bind(&AccessibleNotes::NotifyCaretChange, this, _1, _2, _3, _4));
2331 mpTextView->SetTextChangeBroadcaster(
2332 ::boost::bind(&AccessibleNotes::HandleTextChange, this));
2333 }
2334 }
2335
2336
2337
2338
SetWindow(const cssu::Reference<css::awt::XWindow> & rxContentWindow,const cssu::Reference<css::awt::XWindow> & rxBorderWindow)2339 void AccessibleNotes::SetWindow (
2340 const cssu::Reference<css::awt::XWindow>& rxContentWindow,
2341 const cssu::Reference<css::awt::XWindow>& rxBorderWindow)
2342 {
2343 AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow);
2344
2345 // Set the windows at the children as well, so that every paragraph can
2346 // setup its geometry.
2347 for (::std::vector<rtl::Reference<AccessibleObject> >::const_iterator
2348 iChild(maChildren.begin()),
2349 iEnd(maChildren.end());
2350 iChild!=iEnd;
2351 ++iChild)
2352 {
2353 (*iChild)->SetWindow(rxContentWindow, rxBorderWindow);
2354 }
2355 }
2356
2357
2358
2359
NotifyCaretChange(const sal_Int32 nOldParagraphIndex,const sal_Int32 nOldCharacterIndex,const sal_Int32 nNewParagraphIndex,const sal_Int32 nNewCharacterIndex)2360 void AccessibleNotes::NotifyCaretChange (
2361 const sal_Int32 nOldParagraphIndex,
2362 const sal_Int32 nOldCharacterIndex,
2363 const sal_Int32 nNewParagraphIndex,
2364 const sal_Int32 nNewCharacterIndex)
2365 {
2366 AccessibleFocusManager::Instance()->FocusObject(
2367 nNewParagraphIndex >= 0
2368 ? maChildren[nNewParagraphIndex]
2369 : this);
2370
2371 if (nOldParagraphIndex != nNewParagraphIndex)
2372 {
2373 // Moved caret from one paragraph to another (or showed or
2374 // hid the caret). Move focuse from one accessible
2375 // paragraph to another.
2376 if (nOldParagraphIndex >= 0)
2377 {
2378 maChildren[nOldParagraphIndex]->FireAccessibleEvent(
2379 AccessibleEventId::CARET_CHANGED,
2380 Any(nOldCharacterIndex),
2381 Any(sal_Int32(-1)));
2382 }
2383 if (nNewParagraphIndex >= 0)
2384 {
2385 maChildren[nNewParagraphIndex]->FireAccessibleEvent(
2386 AccessibleEventId::CARET_CHANGED,
2387 Any(sal_Int32(-1)),
2388 Any(nNewCharacterIndex));
2389 }
2390 }
2391 else if (nNewParagraphIndex >= 0)
2392 {
2393 // Caret moved inside one paragraph.
2394 maChildren[nNewParagraphIndex]->FireAccessibleEvent(
2395 AccessibleEventId::CARET_CHANGED,
2396 Any(nOldCharacterIndex),
2397 Any(nNewCharacterIndex));
2398 }
2399 }
2400
2401
2402
2403
HandleTextChange(void)2404 void AccessibleNotes::HandleTextChange (void)
2405 {
2406 SetTextView(mpTextView);
2407 }
2408
2409
2410
2411
2412 //===== AccessibleFocusManager ================================================
2413
2414 ::boost::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::mpInstance;
2415
Instance(void)2416 ::boost::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::Instance (void)
2417 {
2418 if ( ! mpInstance)
2419 {
2420 mpInstance.reset(new AccessibleFocusManager());
2421 }
2422 return mpInstance;
2423 }
2424
2425
2426
2427
AccessibleFocusManager(void)2428 AccessibleFocusManager::AccessibleFocusManager (void)
2429 : maFocusableObjects()
2430 {
2431 }
2432
2433
2434
2435
AddFocusableObject(const::rtl::Reference<PresenterAccessible::AccessibleObject> & rpObject)2436 void AccessibleFocusManager::AddFocusableObject (
2437 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
2438 {
2439 OSL_ASSERT(rpObject.is());
2440 OSL_ASSERT(::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)==maFocusableObjects.end());
2441
2442 maFocusableObjects.push_back(rpObject);
2443 }
2444
2445
2446
2447
RemoveFocusableObject(const::rtl::Reference<PresenterAccessible::AccessibleObject> & rpObject)2448 void AccessibleFocusManager::RemoveFocusableObject (
2449 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
2450 {
2451 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::iterator iObject (
2452 ::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject));
2453
2454 if (iObject != maFocusableObjects.end())
2455 maFocusableObjects.erase(iObject);
2456 else
2457 {
2458 OSL_ASSERT(iObject!=maFocusableObjects.end());
2459 }
2460 }
2461
2462
2463
2464
FocusObject(const::rtl::Reference<PresenterAccessible::AccessibleObject> & rpObject)2465 void AccessibleFocusManager::FocusObject (
2466 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
2467 {
2468 // Remove the focus of any of the other focusable objects.
2469 for (::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::const_iterator
2470 iObject (maFocusableObjects.begin()),
2471 iEnd (maFocusableObjects.end());
2472 iObject != iEnd;
2473 ++iObject)
2474 {
2475 if (*iObject!=rpObject)
2476 (*iObject)->SetIsFocused(false);
2477 }
2478
2479 if (rpObject.is())
2480 rpObject->SetIsFocused(true);
2481 }
2482
2483 } } // end of namespace ::sd::presenter
2484