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