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