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