xref: /trunk/main/sdext/source/presenter/PresenterAccessibility.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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