1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "PresenterAccessibility.hxx"
21 #include "PresenterTextView.hxx"
22 #include "PresenterConfigurationAccess.hxx"
23 #include "PresenterNotesView.hxx"
24 #include "PresenterPaneBase.hxx"
25 #include "PresenterPaneContainer.hxx"
26 #include "PresenterPaneFactory.hxx"
28 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
29 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/accessibility/AccessibleScrollType.hpp>
32 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
33 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
34 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
35 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
36 #include <com/sun/star/accessibility/XAccessibleText.hpp>
37 #include <com/sun/star/awt/XWindow2.hpp>
38 #include <com/sun/star/drawing/framework/XPane.hpp>
39 #include <com/sun/star/drawing/framework/XView.hpp>
40 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
41 #include <cppuhelper/compbase.hxx>
42 #include <cppuhelper/implbase.hxx>
43 #include <o3tl/safeint.hxx>
44 #include <sal/log.hxx>
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::accessibility
;
50 using namespace ::com::sun::star::uno
;
51 using namespace ::com::sun::star::drawing::framework
;
53 //===== PresenterAccessibleObject =============================================
55 namespace sdext::presenter
{
58 typedef ::cppu::WeakComponentImplHelper
<
59 css::accessibility::XAccessible
,
60 css::accessibility::XAccessibleContext
,
61 css::accessibility::XAccessibleComponent
,
62 css::accessibility::XAccessibleEventBroadcaster
,
63 css::awt::XWindowListener
64 > PresenterAccessibleObjectInterfaceBase
;
67 class PresenterAccessible::AccessibleObject
68 : public ::cppu::BaseMutex
,
69 public PresenterAccessibleObjectInterfaceBase
73 const css::lang::Locale
& rLocale
,
74 const sal_Int16 nRole
,
75 const OUString
& rsName
);
76 void LateInitialization();
78 virtual void SetWindow (
79 const css::uno::Reference
<css::awt::XWindow
>& rxContentWindow
,
80 const css::uno::Reference
<css::awt::XWindow
>& rxBorderWindow
);
81 void SetAccessibleParent (const css::uno::Reference
<css::accessibility::XAccessible
>& rxAccessibleParent
);
83 virtual void SAL_CALL
disposing() override
;
85 void AddChild (const ::rtl::Reference
<AccessibleObject
>& rpChild
);
86 void RemoveChild (const ::rtl::Reference
<AccessibleObject
>& rpChild
);
88 void SetIsFocused (const bool bIsFocused
);
89 void SetAccessibleName (const OUString
& rsName
);
91 void FireAccessibleEvent (
92 const sal_Int16 nEventId
,
93 const css::uno::Any
& rOldValue
,
94 const css::uno::Any
& rNewValue
);
96 void UpdateStateSet();
98 //----- XAccessible -------------------------------------------------------
100 virtual css::uno::Reference
<css::accessibility::XAccessibleContext
> SAL_CALL
101 getAccessibleContext() override
;
103 //----- XAccessibleContext ----------------------------------------------
105 virtual sal_Int32 SAL_CALL
getAccessibleChildCount() override
;
107 virtual css::uno::Reference
< css::accessibility::XAccessible
> SAL_CALL
108 getAccessibleChild (sal_Int32 nIndex
) override
;
110 virtual css::uno::Reference
< css::accessibility::XAccessible
> SAL_CALL
getAccessibleParent() override
;
112 virtual sal_Int32 SAL_CALL
getAccessibleIndexInParent() override
;
114 virtual sal_Int16 SAL_CALL
getAccessibleRole() override
;
116 virtual OUString SAL_CALL
getAccessibleDescription() override
;
118 virtual OUString SAL_CALL
getAccessibleName() override
;
120 virtual css::uno::Reference
<css::accessibility::XAccessibleRelationSet
> SAL_CALL
121 getAccessibleRelationSet() override
;
123 virtual css::uno::Reference
<css::accessibility::XAccessibleStateSet
> SAL_CALL
124 getAccessibleStateSet() override
;
126 virtual css::lang::Locale SAL_CALL
getLocale() override
;
128 //----- XAccessibleComponent --------------------------------------------
130 virtual sal_Bool SAL_CALL
containsPoint (
131 const css::awt::Point
& aPoint
) override
;
133 virtual css::uno::Reference
<css::accessibility::XAccessible
> SAL_CALL
134 getAccessibleAtPoint (
135 const css::awt::Point
& aPoint
) override
;
137 virtual css::awt::Rectangle SAL_CALL
getBounds() override
;
139 virtual css::awt::Point SAL_CALL
getLocation() override
;
141 virtual css::awt::Point SAL_CALL
getLocationOnScreen() override
;
143 virtual css::awt::Size SAL_CALL
getSize() override
;
145 virtual void SAL_CALL
grabFocus() override
;
147 virtual sal_Int32 SAL_CALL
getForeground() override
;
149 virtual sal_Int32 SAL_CALL
getBackground() override
;
151 //----- XAccessibleEventBroadcaster --------------------------------------
153 virtual void SAL_CALL
addAccessibleEventListener (
154 const css::uno::Reference
<css::accessibility::XAccessibleEventListener
>& rxListener
) override
;
156 virtual void SAL_CALL
removeAccessibleEventListener (
157 const css::uno::Reference
<css::accessibility::XAccessibleEventListener
>& rxListener
) override
;
159 //----- XWindowListener ---------------------------------------------------
161 virtual void SAL_CALL
windowResized (const css::awt::WindowEvent
& rEvent
) override
;
163 virtual void SAL_CALL
windowMoved (const css::awt::WindowEvent
& rEvent
) override
;
165 virtual void SAL_CALL
windowShown (const css::lang::EventObject
& rEvent
) override
;
167 virtual void SAL_CALL
windowHidden (const css::lang::EventObject
& rEvent
) override
;
169 //----- XEventListener ----------------------------------------------------
171 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
175 css::uno::Reference
<css::awt::XWindow2
> mxContentWindow
;
176 css::uno::Reference
<css::awt::XWindow2
> mxBorderWindow
;
177 const css::lang::Locale maLocale
;
178 const sal_Int16 mnRole
;
179 sal_uInt32 mnStateSet
;
181 css::uno::Reference
<css::accessibility::XAccessible
> mxParentAccessible
;
182 ::std::vector
<rtl::Reference
<AccessibleObject
> > maChildren
;
183 ::std::vector
<Reference
<XAccessibleEventListener
> > maListeners
;
185 virtual awt::Point
GetRelativeLocation();
186 virtual awt::Size
GetSize();
187 virtual awt::Point
GetAbsoluteParentLocation();
189 virtual bool GetWindowState (const sal_Int16 nType
) const;
191 void UpdateState (const sal_Int16 aState
, const bool bValue
);
193 /// @throws css::lang::DisposedException
194 void ThrowIfDisposed() const;
197 //===== AccessibleStateSet ====================================================
200 typedef ::cppu::WeakComponentImplHelper
<
201 css::accessibility::XAccessibleStateSet
202 > AccessibleStateSetInterfaceBase
;
204 class AccessibleStateSet
205 : public ::cppu::BaseMutex
,
206 public AccessibleStateSetInterfaceBase
209 explicit AccessibleStateSet (const sal_Int32 nStateSet
);
211 static sal_uInt32
GetStateMask (const sal_Int16 nType
);
213 //----- XAccessibleStateSet -----------------------------------------------
215 virtual sal_Bool SAL_CALL
isEmpty() override
;
217 virtual sal_Bool SAL_CALL
contains (sal_Int16 nState
) override
;
219 virtual sal_Bool SAL_CALL
containsAll (const css::uno::Sequence
<sal_Int16
>& rStateSet
) override
;
221 virtual css::uno::Sequence
<sal_Int16
> SAL_CALL
getStates() override
;
224 const sal_Int32 mnStateSet
;
227 //===== AccessibleRelationSet =================================================
229 typedef ::cppu::WeakComponentImplHelper
<
230 css::accessibility::XAccessibleRelationSet
231 > AccessibleRelationSetInterfaceBase
;
233 class AccessibleRelationSet
234 : public ::cppu::BaseMutex
,
235 public AccessibleRelationSetInterfaceBase
238 AccessibleRelationSet();
241 const sal_Int16 nRelationType
,
242 const Reference
<XInterface
>& rxObject
);
244 //----- XAccessibleRelationSet --------------------------------------------
246 virtual sal_Int32 SAL_CALL
getRelationCount() override
;
248 virtual AccessibleRelation SAL_CALL
getRelation (sal_Int32 nIndex
) override
;
250 virtual sal_Bool SAL_CALL
containsRelation (sal_Int16 nRelationType
) override
;
252 virtual AccessibleRelation SAL_CALL
getRelationByType (sal_Int16 nRelationType
) override
;
255 ::std::vector
<AccessibleRelation
> maRelations
;
258 //===== PresenterAccessibleParagraph ==========================================
260 typedef ::cppu::ImplInheritanceHelper
<
261 PresenterAccessible::AccessibleObject
,
262 css::accessibility::XAccessibleText
263 > PresenterAccessibleParagraphInterfaceBase
;
266 class PresenterAccessible::AccessibleParagraph
267 : public PresenterAccessibleParagraphInterfaceBase
270 AccessibleParagraph (
271 const css::lang::Locale
& rLocale
,
272 const OUString
& rsName
,
273 const SharedPresenterTextParagraph
& rpParagraph
,
274 const sal_Int32 nParagraphIndex
);
276 //----- XAccessibleContext ------------------------------------------------
278 virtual css::uno::Reference
<css::accessibility::XAccessibleRelationSet
> SAL_CALL
279 getAccessibleRelationSet() override
;
281 //----- XAccessibleText ---------------------------------------------------
283 virtual sal_Int32 SAL_CALL
getCaretPosition() override
;
285 virtual sal_Bool SAL_CALL
setCaretPosition (sal_Int32 nIndex
) override
;
287 virtual sal_Unicode SAL_CALL
getCharacter (sal_Int32 nIndex
) override
;
289 virtual css::uno::Sequence
<css::beans::PropertyValue
> SAL_CALL
290 getCharacterAttributes (
292 const css::uno::Sequence
<OUString
>& rRequestedAttributes
) override
;
294 virtual css::awt::Rectangle SAL_CALL
getCharacterBounds (sal_Int32 nIndex
) override
;
296 virtual sal_Int32 SAL_CALL
getCharacterCount() override
;
298 virtual sal_Int32 SAL_CALL
getIndexAtPoint (const css::awt::Point
& rPoint
) override
;
300 virtual OUString SAL_CALL
getSelectedText() override
;
302 virtual sal_Int32 SAL_CALL
getSelectionStart() override
;
304 virtual sal_Int32 SAL_CALL
getSelectionEnd() override
;
306 virtual sal_Bool SAL_CALL
setSelection (sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) override
;
308 virtual OUString SAL_CALL
getText() override
;
310 virtual OUString SAL_CALL
getTextRange (
311 sal_Int32 nStartIndex
,
312 sal_Int32 nEndIndex
) override
;
314 virtual css::accessibility::TextSegment SAL_CALL
getTextAtIndex (
316 sal_Int16 nTextType
) override
;
318 virtual css::accessibility::TextSegment SAL_CALL
getTextBeforeIndex (
320 sal_Int16 nTextType
) override
;
322 virtual css::accessibility::TextSegment SAL_CALL
getTextBehindIndex (
324 sal_Int16 nTextType
) override
;
326 virtual sal_Bool SAL_CALL
copyText (sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) override
;
328 virtual sal_Bool SAL_CALL
scrollSubstringTo(
329 sal_Int32 nStartIndex
,
331 css::accessibility::AccessibleScrollType aScrollType
) override
;
334 virtual awt::Point
GetRelativeLocation() override
;
335 virtual awt::Size
GetSize() override
;
336 virtual awt::Point
GetAbsoluteParentLocation() override
;
337 virtual bool GetWindowState (const sal_Int16 nType
) const override
;
340 SharedPresenterTextParagraph mpParagraph
;
341 const sal_Int32 mnParagraphIndex
;
344 //===== AccessibleConsole =====================================================
348 class AccessibleConsole
351 static rtl::Reference
<PresenterAccessible::AccessibleObject
> Create (
352 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
353 const lang::Locale
& rLocale
)
355 OUString
sName ("Presenter Console");
356 PresenterConfigurationAccess
aConfiguration (
358 "/org.openoffice.Office.PresenterScreen/",
359 PresenterConfigurationAccess::READ_ONLY
);
360 aConfiguration
.GetConfigurationNode("Presenter/Accessibility/Console/String")
363 rtl::Reference
<PresenterAccessible::AccessibleObject
> pObject (
364 new PresenterAccessible::AccessibleObject(
365 rLocale
, AccessibleRole::PANEL
, sName
));
366 pObject
->LateInitialization();
367 pObject
->UpdateStateSet();
373 //===== AccessiblePreview =====================================================
375 class AccessiblePreview
378 static rtl::Reference
<PresenterAccessible::AccessibleObject
> Create (
379 const Reference
<css::uno::XComponentContext
>& rxContext
,
380 const lang::Locale
& rLocale
,
381 const Reference
<awt::XWindow
>& rxContentWindow
,
382 const Reference
<awt::XWindow
>& rxBorderWindow
)
384 OUString
sName ("Presenter Notes Window");
386 PresenterConfigurationAccess
aConfiguration (
388 "/org.openoffice.Office.PresenterScreen/",
389 PresenterConfigurationAccess::READ_ONLY
);
390 aConfiguration
.GetConfigurationNode("Presenter/Accessibility/Preview/String")
394 rtl::Reference
<PresenterAccessible::AccessibleObject
> pObject (
395 new PresenterAccessible::AccessibleObject(
397 AccessibleRole::LABEL
,
399 pObject
->LateInitialization();
400 pObject
->UpdateStateSet();
401 pObject
->SetWindow(rxContentWindow
, rxBorderWindow
);
407 //===== AccessibleNotes =======================================================
409 class AccessibleNotes
: public PresenterAccessible::AccessibleObject
413 const css::lang::Locale
& rLocale
,
414 const OUString
& rsName
);
416 static rtl::Reference
<PresenterAccessible::AccessibleObject
> Create (
417 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
418 const lang::Locale
& rLocale
,
419 const Reference
<awt::XWindow
>& rxContentWindow
,
420 const Reference
<awt::XWindow
>& rxBorderWindow
,
421 const std::shared_ptr
<PresenterTextView
>& rpTextView
);
423 void SetTextView (const std::shared_ptr
<PresenterTextView
>& rpTextView
);
425 virtual void SetWindow (
426 const css::uno::Reference
<css::awt::XWindow
>& rxContentWindow
,
427 const css::uno::Reference
<css::awt::XWindow
>& rxBorderWindow
) override
;
430 std::shared_ptr
<PresenterTextView
> mpTextView
;
432 void NotifyCaretChange (
433 const sal_Int32 nOldParagraphIndex
,
434 const sal_Int32 nOldCharacterIndex
,
435 const sal_Int32 nNewParagraphIndex
,
436 const sal_Int32 nNewCharacterIndex
);
439 //===== AccessibleFocusManager ================================================
441 /** A singleton class that makes sure that only one accessibility object in
442 the PresenterConsole hierarchy has the focus.
444 class AccessibleFocusManager
447 static std::shared_ptr
<AccessibleFocusManager
> const & Instance();
449 void AddFocusableObject (const ::rtl::Reference
<PresenterAccessible::AccessibleObject
>& rpObject
);
450 void RemoveFocusableObject (const ::rtl::Reference
<PresenterAccessible::AccessibleObject
>& rpObject
);
452 void FocusObject (const ::rtl::Reference
<PresenterAccessible::AccessibleObject
>& rpObject
);
454 ~AccessibleFocusManager();
457 static std::shared_ptr
<AccessibleFocusManager
> mpInstance
;
458 ::std::vector
<rtl::Reference
<PresenterAccessible::AccessibleObject
> > maFocusableObjects
;
459 bool m_isInDtor
= false;
461 AccessibleFocusManager();
466 //===== PresenterAccessible ===================================================
468 PresenterAccessible::PresenterAccessible (
469 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
470 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
471 const Reference
<drawing::framework::XPane
>& rxMainPane
)
472 : PresenterAccessibleInterfaceBase(m_aMutex
),
473 mxComponentContext(rxContext
),
474 mpPresenterController(rpPresenterController
),
475 mxMainPane(rxMainPane
, UNO_QUERY
),
477 mxPreviewContentWindow(),
478 mxPreviewBorderWindow(),
479 mxNotesContentWindow(),
480 mxNotesBorderWindow(),
481 mpAccessibleConsole(),
482 mpAccessiblePreview(),
487 mxMainPane
->setAccessible(this);
490 PresenterAccessible::~PresenterAccessible()
494 PresenterPaneContainer::SharedPaneDescriptor
PresenterAccessible::GetPreviewPane() const
496 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane
;
498 if ( ! mpPresenterController
.is())
501 rtl::Reference
<PresenterPaneContainer
> pContainer (mpPresenterController
->GetPaneContainer());
502 if ( ! pContainer
.is())
505 pPreviewPane
= pContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
);
506 Reference
<drawing::framework::XPane
> xPreviewPane
;
508 xPreviewPane
= pPreviewPane
->mxPane
.get();
509 if ( ! xPreviewPane
.is())
511 pPreviewPane
= pContainer
->FindPaneURL(PresenterPaneFactory::msSlideSorterPaneURL
);
516 void PresenterAccessible::UpdateAccessibilityHierarchy()
518 if ( ! mpPresenterController
.is())
521 Reference
<drawing::framework::XConfigurationController
> xConfigurationController(
522 mpPresenterController
->GetConfigurationController());
523 if ( ! xConfigurationController
.is())
526 rtl::Reference
<PresenterPaneContainer
> pPaneContainer (
527 mpPresenterController
->GetPaneContainer());
528 if ( ! pPaneContainer
.is())
531 if ( ! mpAccessibleConsole
.is())
534 // Get the preview pane (standard or notes view) or the slide overview
536 PresenterPaneContainer::SharedPaneDescriptor
pPreviewPane(GetPreviewPane());
537 Reference
<drawing::framework::XPane
> xPreviewPane
;
539 xPreviewPane
= pPreviewPane
->mxPane
.get();
541 // Get the notes pane.
542 PresenterPaneContainer::SharedPaneDescriptor
pNotesPane(
543 pPaneContainer
->FindPaneURL(PresenterPaneFactory::msNotesPaneURL
));
544 Reference
<drawing::framework::XPane
> xNotesPane
;
546 xNotesPane
= pNotesPane
->mxPane
.get();
548 // Get the notes view.
549 Reference
<drawing::framework::XView
> xNotesView
;
551 xNotesView
= pNotesPane
->mxView
;
552 rtl::Reference
<PresenterNotesView
> pNotesView (
553 dynamic_cast<PresenterNotesView
*>(xNotesView
.get()));
555 UpdateAccessibilityHierarchy(
556 pPreviewPane
? pPreviewPane
->mxContentWindow
: Reference
<awt::XWindow
>(),
557 pPreviewPane
? pPreviewPane
->mxBorderWindow
: Reference
<awt::XWindow
>(),
558 (pPreviewPane
&&pPreviewPane
->mxPane
.is()) ? pPreviewPane
->mxPane
->GetTitle() : OUString(),
559 pNotesPane
? pNotesPane
->mxContentWindow
: Reference
<awt::XWindow
>(),
560 pNotesPane
? pNotesPane
->mxBorderWindow
: Reference
<awt::XWindow
>(),
562 ? pNotesView
->GetTextView()
563 : std::shared_ptr
<PresenterTextView
>());
566 void PresenterAccessible::UpdateAccessibilityHierarchy (
567 const Reference
<awt::XWindow
>& rxPreviewContentWindow
,
568 const Reference
<awt::XWindow
>& rxPreviewBorderWindow
,
569 const OUString
& rsTitle
,
570 const Reference
<awt::XWindow
>& rxNotesContentWindow
,
571 const Reference
<awt::XWindow
>& rxNotesBorderWindow
,
572 const std::shared_ptr
<PresenterTextView
>& rpNotesTextView
)
574 if ( ! mpAccessibleConsole
.is())
577 if (mxPreviewContentWindow
!= rxPreviewContentWindow
)
579 if (mpAccessiblePreview
.is())
581 mpAccessibleConsole
->RemoveChild(mpAccessiblePreview
);
582 mpAccessiblePreview
= nullptr;
585 mxPreviewContentWindow
= rxPreviewContentWindow
;
586 mxPreviewBorderWindow
= rxPreviewBorderWindow
;
588 if (mxPreviewContentWindow
.is())
590 mpAccessiblePreview
= AccessiblePreview::Create(
593 mxPreviewContentWindow
,
594 mxPreviewBorderWindow
);
595 mpAccessibleConsole
->AddChild(mpAccessiblePreview
);
596 mpAccessiblePreview
->SetAccessibleName(rsTitle
);
600 if (mxNotesContentWindow
== rxNotesContentWindow
)
603 if (mpAccessibleNotes
.is())
605 mpAccessibleConsole
->RemoveChild(mpAccessibleNotes
);
606 mpAccessibleNotes
= nullptr;
609 mxNotesContentWindow
= rxNotesContentWindow
;
610 mxNotesBorderWindow
= rxNotesBorderWindow
;
612 if (mxNotesContentWindow
.is())
614 mpAccessibleNotes
= AccessibleNotes::Create(
617 mxNotesContentWindow
,
620 mpAccessibleConsole
->AddChild(mpAccessibleNotes
.get());
624 void PresenterAccessible::NotifyCurrentSlideChange ()
626 if (mpAccessiblePreview
.is())
628 PresenterPaneContainer::SharedPaneDescriptor
pPreviewPane (GetPreviewPane());
629 mpAccessiblePreview
->SetAccessibleName(
630 pPreviewPane
&&pPreviewPane
->mxPane
.is()
631 ? pPreviewPane
->mxPane
->GetTitle()
635 // Play some focus ping-pong to trigger AT tools.
636 //AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
637 AccessibleFocusManager::Instance()->FocusObject(mpAccessiblePreview
);
640 void SAL_CALL
PresenterAccessible::disposing()
642 UpdateAccessibilityHierarchy(
648 std::shared_ptr
<PresenterTextView
>());
650 if (mxMainWindow
.is())
652 mxMainWindow
->removeFocusListener(this);
655 mxMainPane
->setAccessible(nullptr);
658 mpAccessiblePreview
= nullptr;
659 mpAccessibleNotes
= nullptr;
660 mpAccessibleConsole
= nullptr;
663 //----- XAccessible -----------------------------------------------------------
665 Reference
<XAccessibleContext
> SAL_CALL
PresenterAccessible::getAccessibleContext()
667 if ( ! mpAccessibleConsole
.is())
669 Reference
<XPane
> xMainPane (mxMainPane
, UNO_QUERY
);
672 mxMainWindow
= xMainPane
->getWindow();
673 mxMainWindow
->addFocusListener(this);
675 mpAccessibleConsole
= AccessibleConsole::Create(
676 mxComponentContext
, css::lang::Locale());
677 mpAccessibleConsole
->SetWindow(mxMainWindow
, nullptr);
678 mpAccessibleConsole
->SetAccessibleParent(mxAccessibleParent
);
679 UpdateAccessibilityHierarchy();
680 if (mpPresenterController
.is())
681 mpPresenterController
->SetAccessibilityActiveState(true);
683 return mpAccessibleConsole
->getAccessibleContext();
686 //----- XFocusListener ----------------------------------------------------
688 void SAL_CALL
PresenterAccessible::focusGained (const css::awt::FocusEvent
&)
690 SAL_INFO("sdext.presenter", __func__
<< ": PresenterAccessible::focusGained at " << this
691 << " and window " << mxMainWindow
.get());
692 AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole
);
695 void SAL_CALL
PresenterAccessible::focusLost (const css::awt::FocusEvent
&)
697 SAL_INFO("sdext.presenter", __func__
<< ": PresenterAccessible::focusLost at " << this);
698 AccessibleFocusManager::Instance()->FocusObject(nullptr);
701 //----- XEventListener ----------------------------------------------------
703 void SAL_CALL
PresenterAccessible::disposing (const css::lang::EventObject
& rEvent
)
705 if (rEvent
.Source
== mxMainWindow
)
706 mxMainWindow
= nullptr;
709 //----- XInitialize -----------------------------------------------------------
711 void SAL_CALL
PresenterAccessible::initialize (const css::uno::Sequence
<css::uno::Any
>& rArguments
)
713 if (rArguments
.hasElements())
715 mxAccessibleParent
.set(rArguments
[0], UNO_QUERY
);
716 if (mpAccessibleConsole
.is())
717 mpAccessibleConsole
->SetAccessibleParent(mxAccessibleParent
);
721 //===== PresenterAccessible::AccessibleObject =========================================
723 PresenterAccessible::AccessibleObject::AccessibleObject (
724 const lang::Locale
& rLocale
,
725 const sal_Int16 nRole
,
726 const OUString
& rsName
)
727 : PresenterAccessibleObjectInterfaceBase(m_aMutex
),
735 mxParentAccessible(),
741 void PresenterAccessible::AccessibleObject::LateInitialization()
743 AccessibleFocusManager::Instance()->AddFocusableObject(this);
746 void PresenterAccessible::AccessibleObject::SetWindow (
747 const Reference
<awt::XWindow
>& rxContentWindow
,
748 const Reference
<awt::XWindow
>& rxBorderWindow
)
750 Reference
<awt::XWindow2
> xContentWindow (rxContentWindow
, UNO_QUERY
);
752 if (mxContentWindow
.get() == xContentWindow
.get())
755 if (mxContentWindow
.is())
757 mxContentWindow
->removeWindowListener(this);
760 mxContentWindow
= xContentWindow
;
761 mxBorderWindow
.set(rxBorderWindow
, UNO_QUERY
);
763 if (mxContentWindow
.is())
765 mxContentWindow
->addWindowListener(this);
771 void PresenterAccessible::AccessibleObject::SetAccessibleParent (
772 const Reference
<XAccessible
>& rxAccessibleParent
)
774 mxParentAccessible
= rxAccessibleParent
;
777 void SAL_CALL
PresenterAccessible::AccessibleObject::disposing()
779 AccessibleFocusManager::Instance()->RemoveFocusableObject(this);
780 SetWindow(nullptr, nullptr);
783 //----- XAccessible -------------------------------------------------------
785 Reference
<XAccessibleContext
> SAL_CALL
786 PresenterAccessible::AccessibleObject::getAccessibleContext()
793 //----- XAccessibleContext ----------------------------------------------
795 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleObject::getAccessibleChildCount()
799 const sal_Int32
nChildCount (maChildren
.size());
804 Reference
<XAccessible
> SAL_CALL
805 PresenterAccessible::AccessibleObject::getAccessibleChild (sal_Int32 nIndex
)
809 if (nIndex
<0 || nIndex
>=sal_Int32(maChildren
.size()))
810 throw lang::IndexOutOfBoundsException("invalid child index", static_cast<uno::XWeak
*>(this));
812 return Reference
<XAccessible
>(maChildren
[nIndex
].get());
815 Reference
<XAccessible
> SAL_CALL
816 PresenterAccessible::AccessibleObject::getAccessibleParent()
820 return mxParentAccessible
;
824 PresenterAccessible::AccessibleObject::getAccessibleIndexInParent()
828 const Reference
<XAccessible
> xThis (this);
829 if (mxParentAccessible
.is())
831 const Reference
<XAccessibleContext
> xContext (mxParentAccessible
->getAccessibleContext());
832 for (sal_Int32 nIndex
=0,nCount
=xContext
->getAccessibleChildCount();
836 if (xContext
->getAccessibleChild(nIndex
) == xThis
)
845 PresenterAccessible::AccessibleObject::getAccessibleRole()
853 PresenterAccessible::AccessibleObject::getAccessibleDescription()
861 PresenterAccessible::AccessibleObject::getAccessibleName()
868 Reference
<XAccessibleRelationSet
> SAL_CALL
869 PresenterAccessible::AccessibleObject::getAccessibleRelationSet()
876 Reference
<XAccessibleStateSet
> SAL_CALL
877 PresenterAccessible::AccessibleObject::getAccessibleStateSet()
881 return Reference
<XAccessibleStateSet
>(new AccessibleStateSet(mnStateSet
));
884 lang::Locale SAL_CALL
885 PresenterAccessible::AccessibleObject::getLocale()
889 if (mxParentAccessible
.is())
891 Reference
<XAccessibleContext
> xParentContext (mxParentAccessible
->getAccessibleContext());
892 if (xParentContext
.is())
893 return xParentContext
->getLocale();
898 //----- XAccessibleComponent ------------------------------------------------
900 sal_Bool SAL_CALL
PresenterAccessible::AccessibleObject::containsPoint (
901 const awt::Point
& rPoint
)
905 if (mxContentWindow
.is())
907 const awt::Rectangle
aBox (getBounds());
908 return rPoint
.X
>=aBox
.X
910 && rPoint
.X
<aBox
.X
+aBox
.Width
911 && rPoint
.Y
<aBox
.Y
+aBox
.Height
;
917 Reference
<XAccessible
> SAL_CALL
918 PresenterAccessible::AccessibleObject::getAccessibleAtPoint (const awt::Point
&)
922 return Reference
<XAccessible
>();
925 awt::Rectangle SAL_CALL
PresenterAccessible::AccessibleObject::getBounds()
929 const awt::Point
aLocation (GetRelativeLocation());
930 const awt::Size
aSize (GetSize());
932 return awt::Rectangle (aLocation
.X
, aLocation
.Y
, aSize
.Width
, aSize
.Height
);
935 awt::Point SAL_CALL
PresenterAccessible::AccessibleObject::getLocation()
939 const awt::Point
aLocation (GetRelativeLocation());
944 awt::Point SAL_CALL
PresenterAccessible::AccessibleObject::getLocationOnScreen()
948 awt::Point
aRelativeLocation (GetRelativeLocation());
949 awt::Point
aParentLocationOnScreen (GetAbsoluteParentLocation());
952 aRelativeLocation
.X
+ aParentLocationOnScreen
.X
,
953 aRelativeLocation
.Y
+ aParentLocationOnScreen
.Y
);
956 awt::Size SAL_CALL
PresenterAccessible::AccessibleObject::getSize()
960 const awt::Size
aSize (GetSize());
965 void SAL_CALL
PresenterAccessible::AccessibleObject::grabFocus()
968 if (mxBorderWindow
.is())
969 mxBorderWindow
->setFocus();
970 else if (mxContentWindow
.is())
971 mxContentWindow
->setFocus();
974 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleObject::getForeground()
981 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleObject::getBackground()
988 //----- XAccessibleEventBroadcaster -------------------------------------------
990 void SAL_CALL
PresenterAccessible::AccessibleObject::addAccessibleEventListener (
991 const Reference
<XAccessibleEventListener
>& rxListener
)
993 if (!rxListener
.is())
996 const osl::MutexGuard
aGuard(m_aMutex
);
998 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1000 uno::Reference
<uno::XInterface
> xThis (static_cast<XWeak
*>(this), UNO_QUERY
);
1001 rxListener
->disposing (lang::EventObject(xThis
));
1005 maListeners
.push_back(rxListener
);
1009 void SAL_CALL
PresenterAccessible::AccessibleObject::removeAccessibleEventListener (
1010 const Reference
<XAccessibleEventListener
>& rxListener
)
1013 if (rxListener
.is())
1015 const osl::MutexGuard
aGuard(m_aMutex
);
1017 auto const it(std::remove(maListeners
.begin(), maListeners
.end(), rxListener
));
1018 if (it
!= maListeners
.end())
1020 maListeners
.erase(it
);
1025 //----- XWindowListener ---------------------------------------------------
1027 void SAL_CALL
PresenterAccessible::AccessibleObject::windowResized (
1028 const css::awt::WindowEvent
&)
1030 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED
, Any(), Any());
1033 void SAL_CALL
PresenterAccessible::AccessibleObject::windowMoved (
1034 const css::awt::WindowEvent
&)
1036 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED
, Any(), Any());
1039 void SAL_CALL
PresenterAccessible::AccessibleObject::windowShown (
1040 const css::lang::EventObject
&)
1045 void SAL_CALL
PresenterAccessible::AccessibleObject::windowHidden (
1046 const css::lang::EventObject
&)
1051 //----- XEventListener --------------------------------------------------------
1053 void SAL_CALL
PresenterAccessible::AccessibleObject::disposing (const css::lang::EventObject
& rEvent
)
1055 if (rEvent
.Source
== mxContentWindow
)
1057 mxContentWindow
= nullptr;
1058 mxBorderWindow
= nullptr;
1062 SetWindow(nullptr, nullptr);
1066 //----- private ---------------------------------------------------------------
1068 bool PresenterAccessible::AccessibleObject::GetWindowState (const sal_Int16 nType
) const
1072 case AccessibleStateType::ENABLED
:
1073 return mxContentWindow
.is() && mxContentWindow
->isEnabled();
1075 case AccessibleStateType::FOCUSABLE
:
1078 case AccessibleStateType::FOCUSED
:
1081 case AccessibleStateType::SHOWING
:
1082 return mxContentWindow
.is() && mxContentWindow
->isVisible();
1089 void PresenterAccessible::AccessibleObject::UpdateStateSet()
1091 UpdateState(AccessibleStateType::FOCUSABLE
, true);
1092 UpdateState(AccessibleStateType::VISIBLE
, true);
1093 UpdateState(AccessibleStateType::ENABLED
, true);
1094 UpdateState(AccessibleStateType::MULTI_LINE
, true);
1095 UpdateState(AccessibleStateType::SENSITIVE
, true);
1097 UpdateState(AccessibleStateType::ENABLED
, GetWindowState(AccessibleStateType::ENABLED
));
1098 UpdateState(AccessibleStateType::FOCUSED
, GetWindowState(AccessibleStateType::FOCUSED
));
1099 UpdateState(AccessibleStateType::SHOWING
, GetWindowState(AccessibleStateType::SHOWING
));
1100 // UpdateState(AccessibleStateType::ACTIVE, GetWindowState(AccessibleStateType::ACTIVE));
1103 void PresenterAccessible::AccessibleObject::UpdateState(
1104 const sal_Int16 nState
,
1107 const sal_uInt32
nStateMask (AccessibleStateSet::GetStateMask(nState
));
1108 if (((mnStateSet
& nStateMask
)!=0) != bValue
)
1112 mnStateSet
|= nStateMask
;
1113 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED
, Any(), Any(nState
));
1117 mnStateSet
&= ~nStateMask
;
1118 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED
, Any(nState
), Any());
1123 void PresenterAccessible::AccessibleObject::AddChild (
1124 const ::rtl::Reference
<AccessibleObject
>& rpChild
)
1126 maChildren
.push_back(rpChild
);
1127 rpChild
->SetAccessibleParent(this);
1128 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN
, Any(), Any());
1131 void PresenterAccessible::AccessibleObject::RemoveChild (
1132 const ::rtl::Reference
<AccessibleObject
>& rpChild
)
1134 rpChild
->SetAccessibleParent(Reference
<XAccessible
>());
1135 maChildren
.erase(::std::find(maChildren
.begin(), maChildren
.end(), rpChild
));
1136 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN
, Any(), Any());
1139 void PresenterAccessible::AccessibleObject::SetIsFocused (const bool bIsFocused
)
1141 if (mbIsFocused
!= bIsFocused
)
1143 mbIsFocused
= bIsFocused
;
1148 void PresenterAccessible::AccessibleObject::SetAccessibleName (const OUString
& rsName
)
1150 if (msName
!= rsName
)
1152 const OUString
sOldName(msName
);
1154 FireAccessibleEvent(AccessibleEventId::NAME_CHANGED
, Any(sOldName
), Any(msName
));
1158 void PresenterAccessible::AccessibleObject::FireAccessibleEvent (
1159 const sal_Int16 nEventId
,
1160 const uno::Any
& rOldValue
,
1161 const uno::Any
& rNewValue
)
1163 AccessibleEventObject aEventObject
;
1165 aEventObject
.Source
= Reference
<XWeak
>(this);
1166 aEventObject
.EventId
= nEventId
;
1167 aEventObject
.NewValue
= rNewValue
;
1168 aEventObject
.OldValue
= rOldValue
;
1170 ::std::vector
<Reference
<XAccessibleEventListener
> > aListenerCopy(maListeners
);
1171 for (const auto& rxListener
: aListenerCopy
)
1175 rxListener
->notifyEvent(aEventObject
);
1177 catch (const lang::DisposedException
&)
1179 // Listener has been disposed and should have been removed
1181 removeAccessibleEventListener(rxListener
);
1183 catch (const Exception
&)
1185 // Ignore all other exceptions and assume that they are
1186 // caused by a temporary problem.
1191 awt::Point
PresenterAccessible::AccessibleObject::GetRelativeLocation()
1193 awt::Point aLocation
;
1194 if (mxContentWindow
.is())
1196 const awt::Rectangle
aContentBox (mxContentWindow
->getPosSize());
1197 aLocation
.X
= aContentBox
.X
;
1198 aLocation
.Y
= aContentBox
.Y
;
1199 if (mxBorderWindow
.is())
1201 const awt::Rectangle
aBorderBox (mxBorderWindow
->getPosSize());
1202 aLocation
.X
+= aBorderBox
.X
;
1203 aLocation
.Y
+= aBorderBox
.Y
;
1209 awt::Size
PresenterAccessible::AccessibleObject::GetSize()
1211 if (mxContentWindow
.is())
1213 const awt::Rectangle
aBox (mxContentWindow
->getPosSize());
1214 return awt::Size(aBox
.Width
, aBox
.Height
);
1220 awt::Point
PresenterAccessible::AccessibleObject::GetAbsoluteParentLocation()
1222 Reference
<XAccessibleComponent
> xParentComponent
;
1223 if (mxParentAccessible
.is())
1224 xParentComponent
.set( mxParentAccessible
->getAccessibleContext(), UNO_QUERY
);
1225 if (xParentComponent
.is())
1226 return xParentComponent
->getLocationOnScreen();
1228 return awt::Point();
1231 void PresenterAccessible::AccessibleObject::ThrowIfDisposed() const
1233 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1234 throw lang::DisposedException("object has already been disposed", uno::Reference
<uno::XInterface
>(const_cast<uno::XWeak
*>(static_cast<uno::XWeak
const *>(this))));
1237 //===== AccessibleStateSet ====================================================
1239 AccessibleStateSet::AccessibleStateSet (const sal_Int32 nStateSet
)
1240 : AccessibleStateSetInterfaceBase(m_aMutex
),
1241 mnStateSet (nStateSet
)
1245 sal_uInt32
AccessibleStateSet::GetStateMask (const sal_Int16 nState
)
1247 if (nState
<0 || nState
>=sal_Int16(sizeof(sal_uInt32
)*8))
1249 throw RuntimeException("AccessibleStateSet::GetStateMask: invalid state");
1255 //----- XAccessibleStateSet ---------------------------------------------------
1257 sal_Bool SAL_CALL
AccessibleStateSet::isEmpty()
1259 return mnStateSet
==0;
1262 sal_Bool SAL_CALL
AccessibleStateSet::contains (sal_Int16 nState
)
1264 return (mnStateSet
& GetStateMask(nState
)) != 0;
1267 sal_Bool SAL_CALL
AccessibleStateSet::containsAll (const css::uno::Sequence
<sal_Int16
>& rStateSet
)
1269 return std::none_of(rStateSet
.begin(), rStateSet
.end(),
1270 [this](const sal_Int16 nState
) { return (mnStateSet
& GetStateMask(nState
)) == 0; });
1273 css::uno::Sequence
<sal_Int16
> SAL_CALL
AccessibleStateSet::getStates()
1275 ::std::vector
<sal_Int16
> aStates
;
1276 aStates
.reserve(sizeof(mnStateSet
)*8);
1277 for (sal_uInt16 nIndex
=0; nIndex
<sizeof(mnStateSet
)*8; ++nIndex
)
1278 if ((mnStateSet
& GetStateMask(nIndex
)) != 0)
1279 aStates
.push_back(nIndex
);
1280 return Sequence
<sal_Int16
>(aStates
.data(), aStates
.size());
1283 //===== AccessibleRelationSet =================================================
1285 AccessibleRelationSet::AccessibleRelationSet()
1286 : AccessibleRelationSetInterfaceBase(m_aMutex
),
1291 void AccessibleRelationSet::AddRelation (
1292 const sal_Int16 nRelationType
,
1293 const Reference
<XInterface
>& rxObject
)
1295 maRelations
.emplace_back();
1296 maRelations
.back().RelationType
= nRelationType
;
1297 maRelations
.back().TargetSet
.realloc(1);
1298 maRelations
.back().TargetSet
[0] = rxObject
;
1301 //----- XAccessibleRelationSet ------------------------------------------------
1303 sal_Int32 SAL_CALL
AccessibleRelationSet::getRelationCount()
1305 return maRelations
.size();
1308 AccessibleRelation SAL_CALL
AccessibleRelationSet::getRelation (sal_Int32 nIndex
)
1310 if (nIndex
<0 && o3tl::make_unsigned(nIndex
)>=maRelations
.size())
1311 return AccessibleRelation();
1313 return maRelations
[nIndex
];
1316 sal_Bool SAL_CALL
AccessibleRelationSet::containsRelation (sal_Int16 nRelationType
)
1318 return std::any_of(maRelations
.begin(), maRelations
.end(),
1319 [nRelationType
](const AccessibleRelation
& rRelation
) { return rRelation
.RelationType
== nRelationType
; });
1322 AccessibleRelation SAL_CALL
AccessibleRelationSet::getRelationByType (sal_Int16 nRelationType
)
1324 auto iRelation
= std::find_if(maRelations
.begin(), maRelations
.end(),
1325 [nRelationType
](const AccessibleRelation
& rRelation
) { return rRelation
.RelationType
== nRelationType
; });
1326 if (iRelation
!= maRelations
.end())
1328 return AccessibleRelation();
1331 //===== PresenterAccessible::AccessibleParagraph ==============================
1333 PresenterAccessible::AccessibleParagraph::AccessibleParagraph (
1334 const lang::Locale
& rLocale
,
1335 const OUString
& rsName
,
1336 const SharedPresenterTextParagraph
& rpParagraph
,
1337 const sal_Int32 nParagraphIndex
)
1338 : PresenterAccessibleParagraphInterfaceBase(rLocale
, AccessibleRole::PARAGRAPH
, rsName
),
1339 mpParagraph(rpParagraph
),
1340 mnParagraphIndex(nParagraphIndex
)
1344 //----- XAccessibleContext ----------------------------------------------------
1346 Reference
<XAccessibleRelationSet
> SAL_CALL
1347 PresenterAccessible::AccessibleParagraph::getAccessibleRelationSet()
1351 rtl::Reference
<AccessibleRelationSet
> pSet (new AccessibleRelationSet
);
1353 if (mxParentAccessible
.is())
1355 Reference
<XAccessibleContext
> xParentContext (mxParentAccessible
->getAccessibleContext());
1356 if (xParentContext
.is())
1358 if (mnParagraphIndex
>0)
1360 AccessibleRelationType::CONTENT_FLOWS_FROM
,
1361 xParentContext
->getAccessibleChild(mnParagraphIndex
-1));
1363 if (mnParagraphIndex
<xParentContext
->getAccessibleChildCount()-1)
1365 AccessibleRelationType::CONTENT_FLOWS_TO
,
1366 xParentContext
->getAccessibleChild(mnParagraphIndex
+1));
1370 return Reference
<XAccessibleRelationSet
>(pSet
.get());
1373 //----- XAccessibleText -------------------------------------------------------
1375 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleParagraph::getCaretPosition()
1379 sal_Int32
nPosition (-1);
1381 nPosition
= mpParagraph
->GetCaretPosition();
1386 sal_Bool SAL_CALL
PresenterAccessible::AccessibleParagraph::setCaretPosition (sal_Int32 nIndex
)
1392 mpParagraph
->SetCaretPosition(nIndex
);
1399 sal_Unicode SAL_CALL
PresenterAccessible::AccessibleParagraph::getCharacter (sal_Int32 nIndex
)
1404 throw lang::IndexOutOfBoundsException("no text support in current mode", static_cast<uno::XWeak
*>(this));
1405 return mpParagraph
->GetCharacter(nIndex
);
1408 Sequence
<css::beans::PropertyValue
> SAL_CALL
1409 PresenterAccessible::AccessibleParagraph::getCharacterAttributes (
1411 const css::uno::Sequence
<OUString
>& rRequestedAttributes
)
1415 #if OSL_DEBUG_LEVEL > 0
1416 SAL_INFO( "sdext.presenter", __func__
<< " at " << this << ", " << nIndex
<< " returns empty set" );
1417 for (sal_Int32
nAttributeIndex(0), nAttributeCount(rRequestedAttributes
.getLength());
1418 nAttributeIndex
< nAttributeCount
;
1421 SAL_INFO( "sdext.presenter",
1422 " requested attribute " << nAttributeIndex
<< " is " << rRequestedAttributes
[nAttributeIndex
] );
1426 (void)rRequestedAttributes
;
1429 // Character properties are not supported.
1430 return Sequence
<css::beans::PropertyValue
>();
1433 awt::Rectangle SAL_CALL
PresenterAccessible::AccessibleParagraph::getCharacterBounds (
1438 awt::Rectangle aCharacterBox
;
1441 throw lang::IndexOutOfBoundsException("invalid text index", static_cast<uno::XWeak
*>(this));
1443 else if (mpParagraph
)
1445 aCharacterBox
= mpParagraph
->GetCharacterBounds(nIndex
, false);
1446 // Convert coordinates relative to the window origin into absolute
1447 // screen coordinates.
1448 const awt::Point
aWindowLocationOnScreen (getLocationOnScreen());
1449 aCharacterBox
.X
+= aWindowLocationOnScreen
.X
;
1450 aCharacterBox
.Y
+= aWindowLocationOnScreen
.Y
;
1454 throw lang::IndexOutOfBoundsException("no text support in current mode", static_cast<uno::XWeak
*>(this));
1457 return aCharacterBox
;
1460 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleParagraph::getCharacterCount()
1464 sal_Int32
nCount (0);
1466 nCount
= mpParagraph
->GetCharacterCount();
1471 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleParagraph::getIndexAtPoint (
1472 const css::awt::Point
& )
1478 OUString SAL_CALL
PresenterAccessible::AccessibleParagraph::getSelectedText()
1482 return getTextRange(getSelectionStart(), getSelectionEnd());
1485 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleParagraph::getSelectionStart()
1489 return getCaretPosition();
1492 sal_Int32 SAL_CALL
PresenterAccessible::AccessibleParagraph::getSelectionEnd()
1496 return getCaretPosition();
1499 sal_Bool SAL_CALL
PresenterAccessible::AccessibleParagraph::setSelection (
1500 sal_Int32 nStartIndex
,
1505 return setCaretPosition(nStartIndex
);
1508 OUString SAL_CALL
PresenterAccessible::AccessibleParagraph::getText()
1514 sText
= mpParagraph
->GetText();
1519 OUString SAL_CALL
PresenterAccessible::AccessibleParagraph::getTextRange (
1520 sal_Int32 nLocalStartIndex
,
1521 sal_Int32 nLocalEndIndex
)
1528 const TextSegment
aSegment (
1529 mpParagraph
->CreateTextSegment(nLocalStartIndex
, nLocalEndIndex
));
1530 sText
= aSegment
.SegmentText
;
1536 TextSegment SAL_CALL
PresenterAccessible::AccessibleParagraph::getTextAtIndex (
1537 sal_Int32 nLocalCharacterIndex
,
1538 sal_Int16 nTextType
)
1542 TextSegment aSegment
;
1544 aSegment
= mpParagraph
->GetTextSegment(0, nLocalCharacterIndex
, nTextType
);
1549 TextSegment SAL_CALL
PresenterAccessible::AccessibleParagraph::getTextBeforeIndex (
1550 sal_Int32 nLocalCharacterIndex
,
1551 sal_Int16 nTextType
)
1555 TextSegment aSegment
;
1557 aSegment
= mpParagraph
->GetTextSegment(-1, nLocalCharacterIndex
, nTextType
);
1562 TextSegment SAL_CALL
PresenterAccessible::AccessibleParagraph::getTextBehindIndex (
1563 sal_Int32 nLocalCharacterIndex
,
1564 sal_Int16 nTextType
)
1568 TextSegment aSegment
;
1570 aSegment
= mpParagraph
->GetTextSegment(+1, nLocalCharacterIndex
, nTextType
);
1575 sal_Bool SAL_CALL
PresenterAccessible::AccessibleParagraph::copyText (
1581 // Return false because copying to clipboard is not supported.
1582 // It IS supported in the notes view. There is no need to duplicate
1587 sal_Bool SAL_CALL
PresenterAccessible::AccessibleParagraph::scrollSubstringTo(
1590 AccessibleScrollType
)
1595 //----- protected -------------------------------------------------------------
1597 awt::Point
PresenterAccessible::AccessibleParagraph::GetRelativeLocation()
1599 awt::Point
aLocation (AccessibleObject::GetRelativeLocation());
1602 const awt::Point
aParagraphLocation (mpParagraph
->GetRelativeLocation());
1603 aLocation
.X
+= aParagraphLocation
.X
;
1604 aLocation
.Y
+= aParagraphLocation
.Y
;
1610 awt::Size
PresenterAccessible::AccessibleParagraph::GetSize()
1613 return mpParagraph
->GetSize();
1615 return AccessibleObject::GetSize();
1618 awt::Point
PresenterAccessible::AccessibleParagraph::GetAbsoluteParentLocation()
1620 if (mxParentAccessible
.is())
1622 Reference
<XAccessibleContext
> xParentContext
=
1623 mxParentAccessible
->getAccessibleContext();
1624 if (xParentContext
.is())
1626 Reference
<XAccessibleComponent
> xGrandParentComponent(
1627 xParentContext
->getAccessibleParent(), UNO_QUERY
);
1628 if (xGrandParentComponent
.is())
1629 return xGrandParentComponent
->getLocationOnScreen();
1633 return awt::Point();
1636 bool PresenterAccessible::AccessibleParagraph::GetWindowState (const sal_Int16 nType
) const
1640 case AccessibleStateType::EDITABLE
:
1641 return bool(mpParagraph
);
1643 case AccessibleStateType::ACTIVE
:
1647 return AccessibleObject::GetWindowState(nType
);
1651 //===== AccessibleNotes =======================================================
1653 AccessibleNotes::AccessibleNotes (
1654 const css::lang::Locale
& rLocale
,
1655 const OUString
& rsName
)
1656 : AccessibleObject(rLocale
,AccessibleRole::PANEL
,rsName
),
1661 rtl::Reference
<PresenterAccessible::AccessibleObject
> AccessibleNotes::Create (
1662 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
1663 const lang::Locale
& rLocale
,
1664 const Reference
<awt::XWindow
>& rxContentWindow
,
1665 const Reference
<awt::XWindow
>& rxBorderWindow
,
1666 const std::shared_ptr
<PresenterTextView
>& rpTextView
)
1668 OUString
sName ("Presenter Notes Text");
1670 PresenterConfigurationAccess
aConfiguration (
1672 "/org.openoffice.Office.PresenterScreen/",
1673 PresenterConfigurationAccess::READ_ONLY
);
1674 aConfiguration
.GetConfigurationNode("Presenter/Accessibility/Notes/String")
1678 rtl::Reference
<AccessibleNotes
> pObject (
1679 new AccessibleNotes(
1682 pObject
->LateInitialization();
1683 pObject
->SetTextView(rpTextView
);
1684 pObject
->UpdateStateSet();
1685 pObject
->SetWindow(rxContentWindow
, rxBorderWindow
);
1687 return rtl::Reference
<PresenterAccessible::AccessibleObject
>(pObject
.get());
1690 void AccessibleNotes::SetTextView (
1691 const std::shared_ptr
<PresenterTextView
>& rpTextView
)
1693 ::std::vector
<rtl::Reference
<PresenterAccessible::AccessibleObject
> > aChildren
;
1695 // Release any listeners to the current text view.
1698 mpTextView
->GetCaret()->SetCaretMotionBroadcaster(
1699 ::std::function
<void (sal_Int32
,sal_Int32
,sal_Int32
,sal_Int32
)>());
1700 mpTextView
->SetTextChangeBroadcaster(
1701 ::std::function
<void ()>());
1704 mpTextView
= rpTextView
;
1709 // Create a new set of children, one for each paragraph.
1710 const sal_Int32
nParagraphCount (mpTextView
->GetParagraphCount());
1711 for (sal_Int32 nIndex
=0; nIndex
<nParagraphCount
; ++nIndex
)
1713 rtl::Reference
<PresenterAccessible::AccessibleParagraph
> pParagraph (
1714 new PresenterAccessible::AccessibleParagraph(
1715 css::lang::Locale(),
1716 "Paragraph"+OUString::number(nIndex
),
1717 rpTextView
->GetParagraph(nIndex
),
1719 pParagraph
->LateInitialization();
1720 pParagraph
->SetWindow(mxContentWindow
, mxBorderWindow
);
1721 pParagraph
->SetAccessibleParent(this);
1722 aChildren
.emplace_back(pParagraph
.get());
1724 maChildren
.swap(aChildren
);
1725 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN
, Any(), Any());
1727 // Dispose the old children. (This will remove them from the focus
1729 for (const auto& rxChild
: aChildren
)
1731 Reference
<lang::XComponent
> xComponent (static_cast<XWeak
*>(rxChild
.get()), UNO_QUERY
);
1732 if (xComponent
.is())
1733 xComponent
->dispose();
1736 // This class acts as a controller of who broadcasts caret motion
1737 // events and handles text changes. Register the corresponding
1739 mpTextView
->GetCaret()->SetCaretMotionBroadcaster(
1740 [this](sal_Int32 a
, sal_Int32 b
, sal_Int32 c
, sal_Int32 d
)
1741 { return this->NotifyCaretChange(a
, b
, c
, d
); });
1742 mpTextView
->SetTextChangeBroadcaster(
1743 [this]() { return SetTextView(mpTextView
); });
1746 void AccessibleNotes::SetWindow (
1747 const css::uno::Reference
<css::awt::XWindow
>& rxContentWindow
,
1748 const css::uno::Reference
<css::awt::XWindow
>& rxBorderWindow
)
1750 AccessibleObject::SetWindow(rxContentWindow
, rxBorderWindow
);
1752 // Set the windows at the children as well, so that every paragraph can
1753 // setup its geometry.
1754 for (auto& rxChild
: maChildren
)
1756 rxChild
->SetWindow(rxContentWindow
, rxBorderWindow
);
1760 void AccessibleNotes::NotifyCaretChange (
1761 const sal_Int32 nOldParagraphIndex
,
1762 const sal_Int32 nOldCharacterIndex
,
1763 const sal_Int32 nNewParagraphIndex
,
1764 const sal_Int32 nNewCharacterIndex
)
1766 AccessibleFocusManager::Instance()->FocusObject(
1767 nNewParagraphIndex
>= 0
1768 ? maChildren
[nNewParagraphIndex
]
1771 if (nOldParagraphIndex
!= nNewParagraphIndex
)
1773 // Moved caret from one paragraph to another (or showed or
1774 // hid the caret). Move focus from one accessible
1775 // paragraph to another.
1776 if (nOldParagraphIndex
>= 0)
1778 maChildren
[nOldParagraphIndex
]->FireAccessibleEvent(
1779 AccessibleEventId::CARET_CHANGED
,
1780 Any(nOldCharacterIndex
),
1781 Any(sal_Int32(-1)));
1783 if (nNewParagraphIndex
>= 0)
1785 maChildren
[nNewParagraphIndex
]->FireAccessibleEvent(
1786 AccessibleEventId::CARET_CHANGED
,
1788 Any(nNewCharacterIndex
));
1791 else if (nNewParagraphIndex
>= 0)
1793 // Caret moved inside one paragraph.
1794 maChildren
[nNewParagraphIndex
]->FireAccessibleEvent(
1795 AccessibleEventId::CARET_CHANGED
,
1796 Any(nOldCharacterIndex
),
1797 Any(nNewCharacterIndex
));
1802 //===== AccessibleFocusManager ================================================
1804 std::shared_ptr
<AccessibleFocusManager
> AccessibleFocusManager::mpInstance
;
1806 std::shared_ptr
<AccessibleFocusManager
> const & AccessibleFocusManager::Instance()
1810 mpInstance
.reset(new AccessibleFocusManager());
1815 AccessibleFocusManager::AccessibleFocusManager()
1819 AccessibleFocusManager::~AccessibleFocusManager()
1821 // copy member to stack, then drop it - otherwise will get use-after-free
1822 // from AccessibleObject::disposing(), it will call ~Reference *twice*
1823 auto const temp(std::move(maFocusableObjects
));
1828 void AccessibleFocusManager::AddFocusableObject (
1829 const ::rtl::Reference
<PresenterAccessible::AccessibleObject
>& rpObject
)
1831 OSL_ASSERT(rpObject
.is());
1832 OSL_ASSERT(::std::find(maFocusableObjects
.begin(),maFocusableObjects
.end(), rpObject
)==maFocusableObjects
.end());
1834 maFocusableObjects
.push_back(rpObject
);
1837 void AccessibleFocusManager::RemoveFocusableObject (
1838 const ::rtl::Reference
<PresenterAccessible::AccessibleObject
>& rpObject
)
1840 ::std::vector
<rtl::Reference
<PresenterAccessible::AccessibleObject
> >::iterator
iObject (
1841 ::std::find(maFocusableObjects
.begin(),maFocusableObjects
.end(), rpObject
));
1843 if (iObject
!= maFocusableObjects
.end())
1844 maFocusableObjects
.erase(iObject
);
1847 OSL_ASSERT(m_isInDtor
); // in dtor, was removed already
1851 void AccessibleFocusManager::FocusObject (
1852 const ::rtl::Reference
<PresenterAccessible::AccessibleObject
>& rpObject
)
1854 // Remove the focus of any of the other focusable objects.
1855 for (auto& rxObject
: maFocusableObjects
)
1857 if (rxObject
!=rpObject
)
1858 rxObject
->SetIsFocused(false);
1862 rpObject
->SetIsFocused(true);
1865 } // end of namespace ::sd::presenter
1867 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */