LibreOffice Module sd (master) 1
PresenterAccessibility.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include "PresenterTextView.hxx"
24#include "PresenterPaneBase.hxx"
27
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>
43#include <o3tl/safeint.hxx>
44#include <sal/log.hxx>
45
46#include <algorithm>
47#include <utility>
48
49using namespace ::com::sun::star;
50using namespace ::com::sun::star::accessibility;
51using namespace ::com::sun::star::uno;
53
54//===== PresenterAccessibleObject =============================================
55
57
58namespace {
59 typedef ::cppu::WeakComponentImplHelper <
60 css::accessibility::XAccessible,
61 css::accessibility::XAccessibleContext,
62 css::accessibility::XAccessibleComponent,
63 css::accessibility::XAccessibleEventBroadcaster,
64 css::awt::XWindowListener
65 > PresenterAccessibleObjectInterfaceBase;
66}
67
69 : public ::cppu::BaseMutex,
70 public PresenterAccessibleObjectInterfaceBase
71{
72public:
74 css::lang::Locale aLocale,
75 const sal_Int16 nRole,
76 OUString sName);
77 void LateInitialization();
78
79 virtual void SetWindow (
80 const css::uno::Reference<css::awt::XWindow>& rxContentWindow,
81 const css::uno::Reference<css::awt::XWindow>& rxBorderWindow);
82 void SetAccessibleParent (const css::uno::Reference<css::accessibility::XAccessible>& rxAccessibleParent);
83
84 virtual void SAL_CALL disposing() override;
85
86 void AddChild (const ::rtl::Reference<AccessibleObject>& rpChild);
87 void RemoveChild (const ::rtl::Reference<AccessibleObject>& rpChild);
88
89 void SetIsFocused (const bool bIsFocused);
90 void SetAccessibleName (const OUString& rsName);
91
93 const sal_Int16 nEventId,
94 const css::uno::Any& rOldValue,
95 const css::uno::Any& rNewValue);
96
97 void UpdateStateSet();
98
99 //----- XAccessible -------------------------------------------------------
100
101 virtual css::uno::Reference<css::accessibility::XAccessibleContext> SAL_CALL
102 getAccessibleContext() override;
103
104 //----- XAccessibleContext ----------------------------------------------
105
106 virtual sal_Int64 SAL_CALL getAccessibleChildCount() override;
107
108 virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL
109 getAccessibleChild (sal_Int64 nIndex) override;
110
111 virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL getAccessibleParent() override;
112
113 virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override;
114
115 virtual sal_Int16 SAL_CALL getAccessibleRole() override;
116
117 virtual OUString SAL_CALL getAccessibleDescription() override;
118
119 virtual OUString SAL_CALL getAccessibleName() override;
120
121 virtual css::uno::Reference<css::accessibility::XAccessibleRelationSet> SAL_CALL
122 getAccessibleRelationSet() override;
123
124 virtual sal_Int64 SAL_CALL getAccessibleStateSet() override;
125
126 virtual css::lang::Locale SAL_CALL getLocale() override;
127
128 //----- XAccessibleComponent --------------------------------------------
129
130 virtual sal_Bool SAL_CALL containsPoint (
131 const css::awt::Point& aPoint) override;
132
133 virtual css::uno::Reference<css::accessibility::XAccessible> SAL_CALL
135 const css::awt::Point& aPoint) override;
136
137 virtual css::awt::Rectangle SAL_CALL getBounds() override;
138
139 virtual css::awt::Point SAL_CALL getLocation() override;
140
141 virtual css::awt::Point SAL_CALL getLocationOnScreen() override;
142
143 virtual css::awt::Size SAL_CALL getSize() override;
144
145 virtual void SAL_CALL grabFocus() override;
146
147 virtual sal_Int32 SAL_CALL getForeground() override;
148
149 virtual sal_Int32 SAL_CALL getBackground() override;
150
151 //----- XAccessibleEventBroadcaster --------------------------------------
152
153 virtual void SAL_CALL addAccessibleEventListener (
154 const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rxListener) override;
155
156 virtual void SAL_CALL removeAccessibleEventListener (
157 const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rxListener) override;
158
159 //----- XWindowListener ---------------------------------------------------
160
161 virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override;
162
163 virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override;
164
165 virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override;
166
167 virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override;
168
169 //----- XEventListener ----------------------------------------------------
170
171 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override;
172
173protected:
174 OUString msName;
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_Int64 mnStateSet;
181 css::uno::Reference<css::accessibility::XAccessible> mxParentAccessible;
182 ::std::vector<rtl::Reference<AccessibleObject> > maChildren;
183 ::std::vector<Reference<XAccessibleEventListener> > maListeners;
184
185 virtual awt::Point GetRelativeLocation();
186 virtual awt::Size GetSize();
187 virtual awt::Point GetAbsoluteParentLocation();
188
189 virtual bool GetWindowState (const sal_Int64 nType) const;
190
191 void UpdateState (const sal_Int64 aState, const bool bValue);
192
194 void ThrowIfDisposed() const;
195};
196
197namespace {
198
199//===== AccessibleRelationSet =================================================
200
201typedef ::cppu::WeakComponentImplHelper <
202 css::accessibility::XAccessibleRelationSet
203 > AccessibleRelationSetInterfaceBase;
204
205class AccessibleRelationSet
206 : public ::cppu::BaseMutex,
207 public AccessibleRelationSetInterfaceBase
208{
209public:
210 AccessibleRelationSet();
211
212 void AddRelation (
213 const sal_Int16 nRelationType,
214 const Reference<XInterface>& rxObject);
215
216 //----- XAccessibleRelationSet --------------------------------------------
217
218 virtual sal_Int32 SAL_CALL getRelationCount() override;
219
220 virtual AccessibleRelation SAL_CALL getRelation (sal_Int32 nIndex) override;
221
222 virtual sal_Bool SAL_CALL containsRelation (sal_Int16 nRelationType) override;
223
224 virtual AccessibleRelation SAL_CALL getRelationByType (sal_Int16 nRelationType) override;
225
226private:
227 ::std::vector<AccessibleRelation> maRelations;
228};
229
230//===== PresenterAccessibleParagraph ==========================================
231
232typedef ::cppu::ImplInheritanceHelper <
233 PresenterAccessible::AccessibleObject,
234 css::accessibility::XAccessibleText
235 > PresenterAccessibleParagraphInterfaceBase;
236}
237
239 : public PresenterAccessibleParagraphInterfaceBase
240{
241public:
243 const css::lang::Locale& rLocale,
244 const OUString& rsName,
246 const sal_Int32 nParagraphIndex);
247
248 //----- XAccessibleContext ------------------------------------------------
249
250 virtual css::uno::Reference<css::accessibility::XAccessibleRelationSet> SAL_CALL
251 getAccessibleRelationSet() override;
252
253 //----- XAccessibleText ---------------------------------------------------
254
255 virtual sal_Int32 SAL_CALL getCaretPosition() override;
256
257 virtual sal_Bool SAL_CALL setCaretPosition (sal_Int32 nIndex) override;
258
259 virtual sal_Unicode SAL_CALL getCharacter (sal_Int32 nIndex) override;
260
261 virtual css::uno::Sequence<css::beans::PropertyValue> SAL_CALL
263 ::sal_Int32 nIndex,
264 const css::uno::Sequence<OUString>& rRequestedAttributes) override;
265
266 virtual css::awt::Rectangle SAL_CALL getCharacterBounds (sal_Int32 nIndex) override;
267
268 virtual sal_Int32 SAL_CALL getCharacterCount() override;
269
270 virtual sal_Int32 SAL_CALL getIndexAtPoint (const css::awt::Point& rPoint) override;
271
272 virtual OUString SAL_CALL getSelectedText() override;
273
274 virtual sal_Int32 SAL_CALL getSelectionStart() override;
275
276 virtual sal_Int32 SAL_CALL getSelectionEnd() override;
277
278 virtual sal_Bool SAL_CALL setSelection (sal_Int32 nStartIndex, sal_Int32 nEndIndex) override;
279
280 virtual OUString SAL_CALL getText() override;
281
282 virtual OUString SAL_CALL getTextRange (
283 sal_Int32 nStartIndex,
284 sal_Int32 nEndIndex) override;
285
286 virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex (
287 sal_Int32 nIndex,
288 sal_Int16 nTextType) override;
289
290 virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex (
291 sal_Int32 nIndex,
292 sal_Int16 nTextType) override;
293
294 virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex (
295 sal_Int32 nIndex,
296 sal_Int16 nTextType) override;
297
298 virtual sal_Bool SAL_CALL copyText (sal_Int32 nStartIndex, sal_Int32 nEndIndex) override;
299
300 virtual sal_Bool SAL_CALL scrollSubstringTo(
301 sal_Int32 nStartIndex,
302 sal_Int32 nEndIndex,
303 css::accessibility::AccessibleScrollType aScrollType) override;
304
305protected:
306 virtual awt::Point GetRelativeLocation() override;
307 virtual awt::Size GetSize() override;
308 virtual awt::Point GetAbsoluteParentLocation() override;
309 virtual bool GetWindowState (const sal_Int64 nType) const override;
310
311private:
313 const sal_Int32 mnParagraphIndex;
314};
315
316//===== AccessibleConsole =====================================================
317
318namespace {
319
320class AccessibleConsole
321{
322public:
324 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
325 const lang::Locale& rLocale)
326 {
327 OUString sName ("Presenter Console");
328 PresenterConfigurationAccess aConfiguration (
329 rxContext,
330 "/org.openoffice.Office.PresenterScreen/",
332 aConfiguration.GetConfigurationNode("Presenter/Accessibility/Console/String")
333 >>= sName;
334
337 rLocale, AccessibleRole::PANEL, sName));
338 pObject->LateInitialization();
339 pObject->UpdateStateSet();
340
341 return pObject;
342 }
343};
344
345//===== AccessiblePreview =====================================================
346
347class AccessiblePreview
348{
349public:
351 const Reference<css::uno::XComponentContext>& rxContext,
352 const lang::Locale& rLocale,
353 const Reference<awt::XWindow>& rxContentWindow,
354 const Reference<awt::XWindow>& rxBorderWindow)
355 {
356 OUString sName ("Presenter Notes Window");
357 {
358 PresenterConfigurationAccess aConfiguration (
359 rxContext,
360 "/org.openoffice.Office.PresenterScreen/",
362 aConfiguration.GetConfigurationNode("Presenter/Accessibility/Preview/String")
363 >>= sName;
364 }
365
367 new PresenterAccessible::AccessibleObject(
368 rLocale,
369 AccessibleRole::LABEL,
370 sName));
371 pObject->LateInitialization();
372 pObject->UpdateStateSet();
373 pObject->SetWindow(rxContentWindow, rxBorderWindow);
374
375 return pObject;
376 }
377};
378
379//===== AccessibleNotes =======================================================
380
381class AccessibleNotes : public PresenterAccessible::AccessibleObject
382{
383public:
384 AccessibleNotes (
385 const css::lang::Locale& rLocale,
386 const OUString& rsName);
387
389 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
390 const lang::Locale& rLocale,
391 const Reference<awt::XWindow>& rxContentWindow,
392 const Reference<awt::XWindow>& rxBorderWindow,
393 const std::shared_ptr<PresenterTextView>& rpTextView);
394
395 void SetTextView (const std::shared_ptr<PresenterTextView>& rpTextView);
396
397 virtual void SetWindow (
398 const css::uno::Reference<css::awt::XWindow>& rxContentWindow,
399 const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) override;
400
401private:
402 std::shared_ptr<PresenterTextView> mpTextView;
403
404 void NotifyCaretChange (
405 const sal_Int32 nOldParagraphIndex,
406 const sal_Int32 nOldCharacterIndex,
407 const sal_Int32 nNewParagraphIndex,
408 const sal_Int32 nNewCharacterIndex);
409};
410
411//===== AccessibleFocusManager ================================================
412
416class AccessibleFocusManager
417{
418public:
419 static std::shared_ptr<AccessibleFocusManager> const & Instance();
420
421 void AddFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
422 void RemoveFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
423
424 void FocusObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
425
426 ~AccessibleFocusManager();
427
428private:
429 static std::shared_ptr<AccessibleFocusManager> mpInstance;
430 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > maFocusableObjects;
431 bool m_isInDtor = false;
432
433 AccessibleFocusManager();
434};
435
436}
437
438//===== PresenterAccessible ===================================================
439
441 css::uno::Reference<css::uno::XComponentContext> xContext,
442 ::rtl::Reference<PresenterController> xPresenterController,
443 const Reference<drawing::framework::XPane>& rxMainPane)
445 mxComponentContext(std::move(xContext)),
446 mpPresenterController(std::move(xPresenterController)),
447 mxMainPane(rxMainPane, UNO_QUERY)
448{
449 if (mxMainPane.is())
450 mxMainPane->setAccessible(this);
451}
452
454{
455}
456
458{
460
461 if ( ! mpPresenterController.is())
462 return pPreviewPane;
463
464 rtl::Reference<PresenterPaneContainer> pContainer (mpPresenterController->GetPaneContainer());
465 if ( ! pContainer.is())
466 return pPreviewPane;
467
468 pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
469 Reference<drawing::framework::XPane> xPreviewPane;
470 if (pPreviewPane)
471 xPreviewPane = pPreviewPane->mxPane.get();
472 if ( ! xPreviewPane.is())
473 {
474 pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msSlideSorterPaneURL);
475 }
476 return pPreviewPane;
477}
478
480{
481 if ( ! mpPresenterController.is())
482 return;
483
484 Reference<drawing::framework::XConfigurationController> xConfigurationController(
485 mpPresenterController->GetConfigurationController());
486 if ( ! xConfigurationController.is())
487 return;
488
490 mpPresenterController->GetPaneContainer());
491 if ( ! pPaneContainer.is())
492 return;
493
494 if ( ! mpAccessibleConsole.is())
495 return;
496
497 // Get the preview pane (standard or notes view) or the slide overview
498 // pane.
500 Reference<drawing::framework::XPane> xPreviewPane;
501 if (pPreviewPane)
502 xPreviewPane = pPreviewPane->mxPane.get();
503
504 // Get the notes pane.
506 pPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
507 Reference<drawing::framework::XPane> xNotesPane;
508 if (pNotesPane)
509 xNotesPane = pNotesPane->mxPane.get();
510
511 // Get the notes view.
512 Reference<drawing::framework::XView> xNotesView;
513 if (pNotesPane)
514 xNotesView = pNotesPane->mxView;
516 dynamic_cast<PresenterNotesView*>(xNotesView.get()));
517
519 pPreviewPane ? pPreviewPane->mxContentWindow : Reference<awt::XWindow>(),
520 pPreviewPane ? pPreviewPane->mxBorderWindow : Reference<awt::XWindow>(),
521 (pPreviewPane&&pPreviewPane->mxPane.is()) ? pPreviewPane->mxPane->GetTitle() : OUString(),
522 pNotesPane ? pNotesPane->mxContentWindow : Reference<awt::XWindow>(),
523 pNotesPane ? pNotesPane->mxBorderWindow : Reference<awt::XWindow>(),
524 pNotesView.is()
525 ? pNotesView->GetTextView()
526 : std::shared_ptr<PresenterTextView>());
527}
528
530 const Reference<awt::XWindow>& rxPreviewContentWindow,
531 const Reference<awt::XWindow>& rxPreviewBorderWindow,
532 const OUString& rsTitle,
533 const Reference<awt::XWindow>& rxNotesContentWindow,
534 const Reference<awt::XWindow>& rxNotesBorderWindow,
535 const std::shared_ptr<PresenterTextView>& rpNotesTextView)
536{
537 if ( ! mpAccessibleConsole.is())
538 return;
539
540 if (mxPreviewContentWindow != rxPreviewContentWindow)
541 {
542 if (mpAccessiblePreview.is())
543 {
545 mpAccessiblePreview = nullptr;
546 }
547
548 mxPreviewContentWindow = rxPreviewContentWindow;
549 mxPreviewBorderWindow = rxPreviewBorderWindow;
550
551 if (mxPreviewContentWindow.is())
552 {
553 mpAccessiblePreview = AccessiblePreview::Create(
555 lang::Locale(),
559 mpAccessiblePreview->SetAccessibleName(rsTitle);
560 }
561 }
562
563 if (mxNotesContentWindow == rxNotesContentWindow)
564 return;
565
566 if (mpAccessibleNotes.is())
567 {
569 mpAccessibleNotes = nullptr;
570 }
571
572 mxNotesContentWindow = rxNotesContentWindow;
573 mxNotesBorderWindow = rxNotesBorderWindow;
574
575 if (mxNotesContentWindow.is())
576 {
577 mpAccessibleNotes = AccessibleNotes::Create(
579 lang::Locale(),
582 rpNotesTextView);
584 }
585}
586
588{
589 if (mpAccessiblePreview.is())
590 {
592 mpAccessiblePreview->SetAccessibleName(
593 pPreviewPane&&pPreviewPane->mxPane.is()
594 ? pPreviewPane->mxPane->GetTitle()
595 : OUString());
596 }
597
598 // Play some focus ping-pong to trigger AT tools.
599 //AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
600 AccessibleFocusManager::Instance()->FocusObject(mpAccessiblePreview);
601}
602
604{
606 nullptr,
607 nullptr,
608 OUString(),
609 nullptr,
610 nullptr,
611 std::shared_ptr<PresenterTextView>());
612
613 if (mxMainWindow.is())
614 {
615 mxMainWindow->removeFocusListener(this);
616
617 if (mxMainPane.is())
618 mxMainPane->setAccessible(nullptr);
619 }
620
621 mpAccessiblePreview = nullptr;
622 mpAccessibleNotes = nullptr;
623 mpAccessibleConsole = nullptr;
624}
625
626//----- XAccessible -----------------------------------------------------------
627
628Reference<XAccessibleContext> SAL_CALL PresenterAccessible::getAccessibleContext()
629{
630 if ( ! mpAccessibleConsole.is())
631 {
632 Reference<XPane> xMainPane (mxMainPane, UNO_QUERY);
633 if (xMainPane.is())
634 {
635 mxMainWindow = xMainPane->getWindow();
636 mxMainWindow->addFocusListener(this);
637 }
638 mpAccessibleConsole = AccessibleConsole::Create(
639 mxComponentContext, css::lang::Locale());
640 mpAccessibleConsole->SetWindow(mxMainWindow, nullptr);
641 mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent);
643 if (mpPresenterController.is())
644 mpPresenterController->SetAccessibilityActiveState(true);
645 }
646 return mpAccessibleConsole->getAccessibleContext();
647}
648
649//----- XFocusListener ----------------------------------------------------
650
651void SAL_CALL PresenterAccessible::focusGained (const css::awt::FocusEvent&)
652{
653 SAL_INFO("sdext.presenter", __func__ << ": PresenterAccessible::focusGained at " << this
654 << " and window " << mxMainWindow.get());
655 AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
656}
657
658void SAL_CALL PresenterAccessible::focusLost (const css::awt::FocusEvent&)
659{
660 SAL_INFO("sdext.presenter", __func__ << ": PresenterAccessible::focusLost at " << this);
661 AccessibleFocusManager::Instance()->FocusObject(nullptr);
662}
663
664//----- XEventListener ----------------------------------------------------
665
666void SAL_CALL PresenterAccessible::disposing (const css::lang::EventObject& rEvent)
667{
668 if (rEvent.Source == mxMainWindow)
669 mxMainWindow = nullptr;
670}
671
672//----- XInitialize -----------------------------------------------------------
673
674void SAL_CALL PresenterAccessible::initialize (const css::uno::Sequence<css::uno::Any>& rArguments)
675{
676 if (rArguments.hasElements())
677 {
678 mxAccessibleParent.set(rArguments[0], UNO_QUERY);
679 if (mpAccessibleConsole.is())
680 mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent);
681 }
682}
683
684//===== PresenterAccessible::AccessibleObject =========================================
685
687 lang::Locale aLocale,
688 const sal_Int16 nRole,
689 OUString sName)
690 : PresenterAccessibleObjectInterfaceBase(m_aMutex),
691 msName(std::move(sName)),
692 maLocale(std::move(aLocale)),
693 mnRole(nRole),
694 mnStateSet(0),
695 mbIsFocused(false)
696{
697}
698
700{
701 AccessibleFocusManager::Instance()->AddFocusableObject(this);
702}
703
705 const Reference<awt::XWindow>& rxContentWindow,
706 const Reference<awt::XWindow>& rxBorderWindow)
707{
708 Reference<awt::XWindow2> xContentWindow (rxContentWindow, UNO_QUERY);
709
710 if (mxContentWindow.get() == xContentWindow.get())
711 return;
712
713 if (mxContentWindow.is())
714 {
715 mxContentWindow->removeWindowListener(this);
716 }
717
718 mxContentWindow = xContentWindow;
719 mxBorderWindow.set(rxBorderWindow, UNO_QUERY);
720
721 if (mxContentWindow.is())
722 {
723 mxContentWindow->addWindowListener(this);
724 }
725
726 UpdateStateSet();
727}
728
730 const Reference<XAccessible>& rxAccessibleParent)
731{
732 mxParentAccessible = rxAccessibleParent;
733}
734
736{
737 AccessibleFocusManager::Instance()->RemoveFocusableObject(this);
738 SetWindow(nullptr, nullptr);
739}
740
741//----- XAccessible -------------------------------------------------------
742
743Reference<XAccessibleContext> SAL_CALL
745{
746 ThrowIfDisposed();
747
748 return this;
749}
750
751//----- XAccessibleContext ----------------------------------------------
752
754{
755 ThrowIfDisposed();
756
757 return maChildren.size();
758}
759
760Reference<XAccessible> SAL_CALL
762{
763 ThrowIfDisposed();
764
766 throw lang::IndexOutOfBoundsException("invalid child index", static_cast<uno::XWeak*>(this));
767
768 return maChildren[nIndex];
769}
770
771Reference<XAccessible> SAL_CALL
773{
774 ThrowIfDisposed();
775
776 return mxParentAccessible;
777}
778
779sal_Int64 SAL_CALL
781{
782 ThrowIfDisposed();
783
784 const Reference<XAccessible> xThis (this);
785 if (mxParentAccessible.is())
786 {
787 const Reference<XAccessibleContext> xContext (mxParentAccessible->getAccessibleContext());
788 for (sal_Int64 nIndex = 0, nCount=xContext->getAccessibleChildCount();
790 ++nIndex)
791 {
792 if (xContext->getAccessibleChild(nIndex) == xThis)
793 return nIndex;
794 }
795 }
796
797 return 0;
798}
799
800sal_Int16 SAL_CALL
802{
803 ThrowIfDisposed();
804
805 return mnRole;
806}
807
808OUString SAL_CALL
810{
811 ThrowIfDisposed();
812
813 return msName;
814}
815
816OUString SAL_CALL
818{
819 ThrowIfDisposed();
820
821 return msName;
822}
823
824Reference<XAccessibleRelationSet> SAL_CALL
826{
827 ThrowIfDisposed();
828
829 return nullptr;
830}
831
832sal_Int64 SAL_CALL
834{
835 ThrowIfDisposed();
836
837 return mnStateSet;
838}
839
840lang::Locale SAL_CALL
842{
843 ThrowIfDisposed();
844
845 if (mxParentAccessible.is())
846 {
847 Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext());
848 if (xParentContext.is())
849 return xParentContext->getLocale();
850 }
851 return maLocale;
852}
853
854//----- XAccessibleComponent ------------------------------------------------
855
857 const awt::Point& rPoint)
858{
859 ThrowIfDisposed();
860
861 if (mxContentWindow.is())
862 {
863 const awt::Rectangle aBox (getBounds());
864 return rPoint.X>=aBox.X
865 && rPoint.Y>=aBox.Y
866 && rPoint.X<aBox.X+aBox.Width
867 && rPoint.Y<aBox.Y+aBox.Height;
868 }
869 else
870 return false;
871}
872
873Reference<XAccessible> SAL_CALL
875{
876 ThrowIfDisposed();
877
878 return Reference<XAccessible>();
879}
880
882{
883 ThrowIfDisposed();
884
885 const awt::Point aLocation (GetRelativeLocation());
886 const awt::Size aSize (GetSize());
887
888 return awt::Rectangle (aLocation.X, aLocation.Y, aSize.Width, aSize.Height);
889}
890
892{
893 ThrowIfDisposed();
894
895 const awt::Point aLocation (GetRelativeLocation());
896
897 return aLocation;
898}
899
901{
902 ThrowIfDisposed();
903
904 awt::Point aRelativeLocation (GetRelativeLocation());
905 awt::Point aParentLocationOnScreen (GetAbsoluteParentLocation());
906
907 return awt::Point(
908 aRelativeLocation.X + aParentLocationOnScreen.X,
909 aRelativeLocation.Y + aParentLocationOnScreen.Y);
910}
911
913{
914 ThrowIfDisposed();
915
916 const awt::Size aSize (GetSize());
917
918 return aSize;
919}
920
922{
923 ThrowIfDisposed();
924 if (mxBorderWindow.is())
925 mxBorderWindow->setFocus();
926 else if (mxContentWindow.is())
927 mxContentWindow->setFocus();
928}
929
931{
932 ThrowIfDisposed();
933
934 return 0x00ffffff;
935}
936
938{
939 ThrowIfDisposed();
940
941 return 0x00000000;
942}
943
944//----- XAccessibleEventBroadcaster -------------------------------------------
945
947 const Reference<XAccessibleEventListener>& rxListener)
948{
949 if (!rxListener.is())
950 return;
951
952 const osl::MutexGuard aGuard(m_aMutex);
953
954 if (rBHelper.bDisposed || rBHelper.bInDispose)
955 {
956 uno::Reference<uno::XInterface> xThis (static_cast<XWeak*>(this), UNO_QUERY);
957 rxListener->disposing (lang::EventObject(xThis));
958 }
959 else
960 {
961 maListeners.push_back(rxListener);
962 }
963}
964
966 const Reference<XAccessibleEventListener>& rxListener)
967{
968 ThrowIfDisposed();
969 if (rxListener.is())
970 {
971 const osl::MutexGuard aGuard(m_aMutex);
972
973 auto const it(std::remove(maListeners.begin(), maListeners.end(), rxListener));
974 if (it != maListeners.end())
975 {
976 maListeners.erase(it);
977 }
978 }
979}
980
981//----- XWindowListener ---------------------------------------------------
982
984 const css::awt::WindowEvent&)
985{
986 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any());
987}
988
990 const css::awt::WindowEvent&)
991{
992 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any());
993}
994
996 const css::lang::EventObject&)
997{
998 UpdateStateSet();
999}
1000
1002 const css::lang::EventObject&)
1003{
1004 UpdateStateSet();
1005}
1006
1007//----- XEventListener --------------------------------------------------------
1008
1009void SAL_CALL PresenterAccessible::AccessibleObject::disposing (const css::lang::EventObject& rEvent)
1010{
1011 if (rEvent.Source == mxContentWindow)
1012 {
1013 mxContentWindow = nullptr;
1014 mxBorderWindow = nullptr;
1015 }
1016 else
1017 {
1018 SetWindow(nullptr, nullptr);
1019 }
1020}
1021
1022//----- private ---------------------------------------------------------------
1023
1025{
1026 switch (nType)
1027 {
1028 case AccessibleStateType::ENABLED:
1029 return mxContentWindow.is() && mxContentWindow->isEnabled();
1030
1031 case AccessibleStateType::FOCUSABLE:
1032 return true;
1033
1034 case AccessibleStateType::FOCUSED:
1035 return mbIsFocused;
1036
1037 case AccessibleStateType::SHOWING:
1038 return mxContentWindow.is() && mxContentWindow->isVisible();
1039
1040 default:
1041 return false;
1042 }
1043}
1044
1046{
1047 UpdateState(AccessibleStateType::FOCUSABLE, true);
1049 UpdateState(AccessibleStateType::ENABLED, true);
1050 UpdateState(AccessibleStateType::MULTI_LINE, true);
1051 UpdateState(AccessibleStateType::SENSITIVE, true);
1052
1053 UpdateState(AccessibleStateType::ENABLED, GetWindowState(AccessibleStateType::ENABLED));
1054 UpdateState(AccessibleStateType::FOCUSED, GetWindowState(AccessibleStateType::FOCUSED));
1055 UpdateState(AccessibleStateType::SHOWING, GetWindowState(AccessibleStateType::SHOWING));
1056 // UpdateState(AccessibleStateType::ACTIVE, GetWindowState(AccessibleStateType::ACTIVE));
1057}
1058
1060 const sal_Int64 nState,
1061 const bool bValue)
1062{
1063 if (((mnStateSet & nState) != 0) == bValue)
1064 return;
1065 if (bValue)
1066 {
1067 mnStateSet |= nState;
1068 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(), Any(nState));
1069 }
1070 else
1071 {
1072 mnStateSet &= ~nState;
1073 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(nState), Any());
1074 }
1075}
1076
1078 const ::rtl::Reference<AccessibleObject>& rpChild)
1079{
1080 maChildren.push_back(rpChild);
1081 rpChild->SetAccessibleParent(this);
1082 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
1083}
1084
1086 const ::rtl::Reference<AccessibleObject>& rpChild)
1087{
1088 rpChild->SetAccessibleParent(Reference<XAccessible>());
1089 maChildren.erase(::std::find(maChildren.begin(), maChildren.end(), rpChild));
1090 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
1091}
1092
1094{
1095 if (mbIsFocused != bIsFocused)
1096 {
1097 mbIsFocused = bIsFocused;
1098 UpdateStateSet();
1099 }
1100}
1101
1103{
1104 if (msName != rsName)
1105 {
1106 const OUString sOldName(msName);
1107 msName = rsName;
1108 FireAccessibleEvent(AccessibleEventId::NAME_CHANGED, Any(sOldName), Any(msName));
1109 }
1110}
1111
1113 const sal_Int16 nEventId,
1114 const uno::Any& rOldValue,
1115 const uno::Any& rNewValue )
1116{
1117 AccessibleEventObject aEventObject;
1118
1119 aEventObject.Source = Reference<XWeak>(this);
1120 aEventObject.EventId = nEventId;
1121 aEventObject.NewValue = rNewValue;
1122 aEventObject.OldValue = rOldValue;
1123
1124 ::std::vector<Reference<XAccessibleEventListener> > aListenerCopy(maListeners);
1125 for (const auto& rxListener : aListenerCopy)
1126 {
1127 try
1128 {
1129 rxListener->notifyEvent(aEventObject);
1130 }
1131 catch (const lang::DisposedException&)
1132 {
1133 // Listener has been disposed and should have been removed
1134 // already.
1135 removeAccessibleEventListener(rxListener);
1136 }
1137 catch (const Exception&)
1138 {
1139 // Ignore all other exceptions and assume that they are
1140 // caused by a temporary problem.
1141 }
1142 }
1143}
1144
1146{
1147 awt::Point aLocation;
1148 if (mxContentWindow.is())
1149 {
1150 const awt::Rectangle aContentBox (mxContentWindow->getPosSize());
1151 aLocation.X = aContentBox.X;
1152 aLocation.Y = aContentBox.Y;
1153 if (mxBorderWindow.is())
1154 {
1155 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
1156 aLocation.X += aBorderBox.X;
1157 aLocation.Y += aBorderBox.Y;
1158 }
1159 }
1160 return aLocation;
1161}
1162
1164{
1165 if (mxContentWindow.is())
1166 {
1167 const awt::Rectangle aBox (mxContentWindow->getPosSize());
1168 return awt::Size(aBox.Width, aBox.Height);
1169 }
1170 else
1171 return awt::Size();
1172}
1173
1175{
1176 Reference<XAccessibleComponent> xParentComponent;
1177 if (mxParentAccessible.is())
1178 xParentComponent.set( mxParentAccessible->getAccessibleContext(), UNO_QUERY);
1179 if (xParentComponent.is())
1180 return xParentComponent->getLocationOnScreen();
1181 else
1182 return awt::Point();
1183}
1184
1186{
1187 if (rBHelper.bDisposed || rBHelper.bInDispose)
1188 throw lang::DisposedException("object has already been disposed", uno::Reference<uno::XInterface>(const_cast<uno::XWeak*>(static_cast<uno::XWeak const *>(this))));
1189}
1190
1191
1192//===== AccessibleRelationSet =================================================
1193
1194AccessibleRelationSet::AccessibleRelationSet()
1195 : AccessibleRelationSetInterfaceBase(m_aMutex)
1196{
1197}
1198
1199void AccessibleRelationSet::AddRelation (
1200 const sal_Int16 nRelationType,
1201 const Reference<XInterface>& rxObject)
1202{
1203 maRelations.emplace_back();
1204 maRelations.back().RelationType = nRelationType;
1205 maRelations.back().TargetSet = { rxObject };
1206}
1207
1208//----- XAccessibleRelationSet ------------------------------------------------
1209
1210sal_Int32 SAL_CALL AccessibleRelationSet::getRelationCount()
1211{
1212 return maRelations.size();
1213}
1214
1215AccessibleRelation SAL_CALL AccessibleRelationSet::getRelation (sal_Int32 nIndex)
1216{
1217 if (nIndex<0 && o3tl::make_unsigned(nIndex)>=maRelations.size())
1218 return AccessibleRelation();
1219 else
1220 return maRelations[nIndex];
1221}
1222
1223sal_Bool SAL_CALL AccessibleRelationSet::containsRelation (sal_Int16 nRelationType)
1224{
1225 return std::any_of(maRelations.begin(), maRelations.end(),
1226 [nRelationType](const AccessibleRelation& rRelation) { return rRelation.RelationType == nRelationType; });
1227}
1228
1229AccessibleRelation SAL_CALL AccessibleRelationSet::getRelationByType (sal_Int16 nRelationType)
1230{
1231 auto iRelation = std::find_if(maRelations.begin(), maRelations.end(),
1232 [nRelationType](const AccessibleRelation& rRelation) { return rRelation.RelationType == nRelationType; });
1233 if (iRelation != maRelations.end())
1234 return *iRelation;
1235 return AccessibleRelation();
1236}
1237
1238//===== PresenterAccessible::AccessibleParagraph ==============================
1239
1241 const lang::Locale& rLocale,
1242 const OUString& rsName,
1244 const sal_Int32 nParagraphIndex)
1245 : PresenterAccessibleParagraphInterfaceBase(rLocale, AccessibleRole::PARAGRAPH, rsName),
1246 mpParagraph(std::move(xParagraph)),
1247 mnParagraphIndex(nParagraphIndex)
1248{
1249}
1250
1251//----- XAccessibleContext ----------------------------------------------------
1252
1253Reference<XAccessibleRelationSet> SAL_CALL
1255{
1256 ThrowIfDisposed();
1257
1258 rtl::Reference<AccessibleRelationSet> pSet (new AccessibleRelationSet);
1259
1260 if (mxParentAccessible.is())
1261 {
1262 Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext());
1263 if (xParentContext.is())
1264 {
1265 if (mnParagraphIndex>0)
1266 pSet->AddRelation(
1267 AccessibleRelationType::CONTENT_FLOWS_FROM,
1268 xParentContext->getAccessibleChild(mnParagraphIndex-1));
1269
1270 if (mnParagraphIndex<xParentContext->getAccessibleChildCount()-1)
1271 pSet->AddRelation(
1272 AccessibleRelationType::CONTENT_FLOWS_TO,
1273 xParentContext->getAccessibleChild(mnParagraphIndex+1));
1274 }
1275 }
1276
1277 return pSet;
1278}
1279
1280//----- XAccessibleText -------------------------------------------------------
1281
1283{
1284 ThrowIfDisposed();
1285
1286 sal_Int32 nPosition (-1);
1287 if (mpParagraph)
1288 nPosition = mpParagraph->GetCaretPosition();
1289
1290 return nPosition;
1291}
1292
1294{
1295 ThrowIfDisposed();
1296
1297 if (mpParagraph)
1298 {
1299 mpParagraph->SetCaretPosition(nIndex);
1300 return true;
1301 }
1302 else
1303 return false;
1304}
1305
1307{
1308 ThrowIfDisposed();
1309
1310 if (!mpParagraph)
1311 throw lang::IndexOutOfBoundsException("no text support in current mode", static_cast<uno::XWeak*>(this));
1312 return mpParagraph->GetCharacter(nIndex);
1313}
1314
1315Sequence<css::beans::PropertyValue> SAL_CALL
1317 ::sal_Int32 nIndex,
1318 const css::uno::Sequence<OUString>& rRequestedAttributes)
1319{
1320 ThrowIfDisposed();
1321
1322#if OSL_DEBUG_LEVEL > 0
1323 SAL_INFO( "sdext.presenter", __func__ << " at " << this << ", " << nIndex << " returns empty set" );
1324 for (sal_Int32 nAttributeIndex(0), nAttributeCount(rRequestedAttributes.getLength());
1325 nAttributeIndex < nAttributeCount;
1326 ++nAttributeIndex)
1327 {
1328 SAL_INFO( "sdext.presenter",
1329 " requested attribute " << nAttributeIndex << " is " << rRequestedAttributes[nAttributeIndex] );
1330 }
1331#else
1332 (void)nIndex;
1333 (void)rRequestedAttributes;
1334#endif
1335
1336 // Character properties are not supported.
1337 return Sequence<css::beans::PropertyValue>();
1338}
1339
1341 sal_Int32 nIndex)
1342{
1343 ThrowIfDisposed();
1344
1345 awt::Rectangle aCharacterBox;
1346 if (nIndex < 0)
1347 {
1348 throw lang::IndexOutOfBoundsException("invalid text index", static_cast<uno::XWeak*>(this));
1349 }
1350 else if (mpParagraph)
1351 {
1352 aCharacterBox = mpParagraph->GetCharacterBounds(nIndex, false);
1353 // Convert coordinates relative to the window origin into absolute
1354 // screen coordinates.
1355 const awt::Point aWindowLocationOnScreen (getLocationOnScreen());
1356 aCharacterBox.X += aWindowLocationOnScreen.X;
1357 aCharacterBox.Y += aWindowLocationOnScreen.Y;
1358 }
1359 else
1360 {
1361 throw lang::IndexOutOfBoundsException("no text support in current mode", static_cast<uno::XWeak*>(this));
1362 }
1363
1364 return aCharacterBox;
1365}
1366
1368{
1369 ThrowIfDisposed();
1370
1371 sal_Int32 nCount (0);
1372 if (mpParagraph)
1373 nCount = mpParagraph->GetCharacterCount();
1374
1375 return nCount;
1376}
1377
1379 const css::awt::Point& )
1380{
1381 ThrowIfDisposed();
1382 return -1;
1383}
1384
1386{
1387 ThrowIfDisposed();
1388
1389 return getTextRange(getSelectionStart(), getSelectionEnd());
1390}
1391
1393{
1394 ThrowIfDisposed();
1395
1396 return getCaretPosition();
1397}
1398
1400{
1401 ThrowIfDisposed();
1402
1403 return getCaretPosition();
1404}
1405
1407 sal_Int32 nStartIndex,
1408 sal_Int32)
1409{
1410 ThrowIfDisposed();
1411
1412 return setCaretPosition(nStartIndex);
1413}
1414
1416{
1417 ThrowIfDisposed();
1418
1419 OUString sText;
1420 if (mpParagraph)
1421 sText = mpParagraph->GetText();
1422
1423 return sText;
1424}
1425
1427 sal_Int32 nLocalStartIndex,
1428 sal_Int32 nLocalEndIndex)
1429{
1430 ThrowIfDisposed();
1431
1432 OUString sText;
1433 if (mpParagraph)
1434 {
1435 const TextSegment aSegment (
1436 mpParagraph->CreateTextSegment(nLocalStartIndex, nLocalEndIndex));
1437 sText = aSegment.SegmentText;
1438 }
1439
1440 return sText;
1441}
1442
1444 sal_Int32 nLocalCharacterIndex,
1445 sal_Int16 nTextType)
1446{
1447 ThrowIfDisposed();
1448
1449 TextSegment aSegment;
1450 if (mpParagraph)
1451 aSegment = mpParagraph->GetTextSegment(0, nLocalCharacterIndex, nTextType);
1452
1453 return aSegment;
1454}
1455
1457 sal_Int32 nLocalCharacterIndex,
1458 sal_Int16 nTextType)
1459{
1460 ThrowIfDisposed();
1461
1462 TextSegment aSegment;
1463 if (mpParagraph)
1464 aSegment = mpParagraph->GetTextSegment(-1, nLocalCharacterIndex, nTextType);
1465
1466 return aSegment;
1467}
1468
1470 sal_Int32 nLocalCharacterIndex,
1471 sal_Int16 nTextType)
1472{
1473 ThrowIfDisposed();
1474
1475 TextSegment aSegment;
1476 if (mpParagraph)
1477 aSegment = mpParagraph->GetTextSegment(+1, nLocalCharacterIndex, nTextType);
1478
1479 return aSegment;
1480}
1481
1483 sal_Int32,
1484 sal_Int32)
1485{
1486 ThrowIfDisposed();
1487
1488 // Return false because copying to clipboard is not supported.
1489 // It IS supported in the notes view. There is no need to duplicate
1490 // this here.
1491 return false;
1492}
1493
1495 sal_Int32,
1496 sal_Int32,
1497 AccessibleScrollType)
1498{
1499 return false;
1500}
1501
1502//----- protected -------------------------------------------------------------
1503
1505{
1506 awt::Point aLocation (AccessibleObject::GetRelativeLocation());
1507 if (mpParagraph)
1508 {
1509 const awt::Point aParagraphLocation (mpParagraph->GetRelativeLocation());
1510 aLocation.X += aParagraphLocation.X;
1511 aLocation.Y += aParagraphLocation.Y;
1512 }
1513
1514 return aLocation;
1515}
1516
1518{
1519 if (mpParagraph)
1520 return mpParagraph->GetSize();
1521 else
1523}
1524
1526{
1527 if (mxParentAccessible.is())
1528 {
1529 Reference<XAccessibleContext> xParentContext =
1530 mxParentAccessible->getAccessibleContext();
1531 if (xParentContext.is())
1532 {
1533 Reference<XAccessibleComponent> xGrandParentComponent(
1534 xParentContext->getAccessibleParent(), UNO_QUERY);
1535 if (xGrandParentComponent.is())
1536 return xGrandParentComponent->getLocationOnScreen();
1537 }
1538 }
1539
1540 return awt::Point();
1541}
1542
1544{
1545 switch (nType)
1546 {
1547 case AccessibleStateType::EDITABLE:
1548 return bool(mpParagraph);
1549
1550 case AccessibleStateType::ACTIVE:
1551 return true;
1552
1553 default:
1555 }
1556}
1557
1558//===== AccessibleNotes =======================================================
1559
1560AccessibleNotes::AccessibleNotes (
1561 const css::lang::Locale& rLocale,
1562 const OUString& rsName)
1563 : AccessibleObject(rLocale,AccessibleRole::PANEL,rsName)
1564{
1565}
1566
1568 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
1569 const lang::Locale& rLocale,
1570 const Reference<awt::XWindow>& rxContentWindow,
1571 const Reference<awt::XWindow>& rxBorderWindow,
1572 const std::shared_ptr<PresenterTextView>& rpTextView)
1573{
1574 OUString sName ("Presenter Notes Text");
1575 {
1576 PresenterConfigurationAccess aConfiguration (
1577 rxContext,
1578 "/org.openoffice.Office.PresenterScreen/",
1580 aConfiguration.GetConfigurationNode("Presenter/Accessibility/Notes/String")
1581 >>= sName;
1582 }
1583
1585 new AccessibleNotes(
1586 rLocale,
1587 sName));
1588 pObject->LateInitialization();
1589 pObject->SetTextView(rpTextView);
1590 pObject->UpdateStateSet();
1591 pObject->SetWindow(rxContentWindow, rxBorderWindow);
1592
1593 return pObject;
1594}
1595
1596void AccessibleNotes::SetTextView (
1597 const std::shared_ptr<PresenterTextView>& rpTextView)
1598{
1599 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > aChildren;
1600
1601 // Release any listeners to the current text view.
1602 if (mpTextView)
1603 {
1604 mpTextView->GetCaret()->SetCaretMotionBroadcaster(
1605 ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)>());
1606 mpTextView->SetTextChangeBroadcaster(
1607 ::std::function<void ()>());
1608 }
1609
1610 mpTextView = rpTextView;
1611
1612 if (!mpTextView)
1613 return;
1614
1615 // Create a new set of children, one for each paragraph.
1616 const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount());
1617 for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex)
1618 {
1620 new PresenterAccessible::AccessibleParagraph(
1621 css::lang::Locale(),
1622 "Paragraph"+OUString::number(nIndex),
1623 rpTextView->GetParagraph(nIndex),
1624 nIndex));
1625 pParagraph->LateInitialization();
1626 pParagraph->SetWindow(mxContentWindow, mxBorderWindow);
1627 pParagraph->SetAccessibleParent(this);
1628 aChildren.emplace_back(pParagraph.get());
1629 }
1630 maChildren.swap(aChildren);
1631 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
1632
1633 // Dispose the old children. (This will remove them from the focus
1634 // manager).
1635 for (const auto& rxChild : aChildren)
1636 {
1637 Reference<lang::XComponent> xComponent = rxChild;
1638 if (xComponent.is())
1639 xComponent->dispose();
1640 }
1641
1642 // This class acts as a controller of who broadcasts caret motion
1643 // events and handles text changes. Register the corresponding
1644 // listeners here.
1645 mpTextView->GetCaret()->SetCaretMotionBroadcaster(
1646 [this](sal_Int32 a, sal_Int32 b, sal_Int32 c, sal_Int32 d)
1647 { return this->NotifyCaretChange(a, b, c, d); });
1648 mpTextView->SetTextChangeBroadcaster(
1649 [this]() { return SetTextView(mpTextView); });
1650}
1651
1652void AccessibleNotes::SetWindow (
1653 const css::uno::Reference<css::awt::XWindow>& rxContentWindow,
1654 const css::uno::Reference<css::awt::XWindow>& rxBorderWindow)
1655{
1656 AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow);
1657
1658 // Set the windows at the children as well, so that every paragraph can
1659 // setup its geometry.
1660 for (auto& rxChild : maChildren)
1661 {
1662 rxChild->SetWindow(rxContentWindow, rxBorderWindow);
1663 }
1664}
1665
1666void AccessibleNotes::NotifyCaretChange (
1667 const sal_Int32 nOldParagraphIndex,
1668 const sal_Int32 nOldCharacterIndex,
1669 const sal_Int32 nNewParagraphIndex,
1670 const sal_Int32 nNewCharacterIndex)
1671{
1672 AccessibleFocusManager::Instance()->FocusObject(
1673 nNewParagraphIndex >= 0
1674 ? maChildren[nNewParagraphIndex]
1675 : this);
1676
1677 if (nOldParagraphIndex != nNewParagraphIndex)
1678 {
1679 // Moved caret from one paragraph to another (or showed or
1680 // hid the caret). Move focus from one accessible
1681 // paragraph to another.
1682 if (nOldParagraphIndex >= 0)
1683 {
1684 maChildren[nOldParagraphIndex]->FireAccessibleEvent(
1685 AccessibleEventId::CARET_CHANGED,
1686 Any(nOldCharacterIndex),
1687 Any(sal_Int32(-1)));
1688 }
1689 if (nNewParagraphIndex >= 0)
1690 {
1691 maChildren[nNewParagraphIndex]->FireAccessibleEvent(
1692 AccessibleEventId::CARET_CHANGED,
1693 Any(sal_Int32(-1)),
1694 Any(nNewCharacterIndex));
1695 }
1696 }
1697 else if (nNewParagraphIndex >= 0)
1698 {
1699 // Caret moved inside one paragraph.
1700 maChildren[nNewParagraphIndex]->FireAccessibleEvent(
1701 AccessibleEventId::CARET_CHANGED,
1702 Any(nOldCharacterIndex),
1703 Any(nNewCharacterIndex));
1704 }
1705}
1706
1707
1708//===== AccessibleFocusManager ================================================
1709
1710std::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::mpInstance;
1711
1712std::shared_ptr<AccessibleFocusManager> const & AccessibleFocusManager::Instance()
1713{
1714 if ( ! mpInstance)
1715 {
1716 mpInstance.reset(new AccessibleFocusManager());
1717 }
1718 return mpInstance;
1719}
1720
1721AccessibleFocusManager::AccessibleFocusManager()
1722{
1723}
1724
1725AccessibleFocusManager::~AccessibleFocusManager()
1726{
1727 // copy member to stack, then drop it - otherwise will get use-after-free
1728 // from AccessibleObject::disposing(), it will call ~Reference *twice*
1729 auto const temp(std::move(maFocusableObjects));
1730 (void) temp;
1731 m_isInDtor = true;
1732}
1733
1734void AccessibleFocusManager::AddFocusableObject (
1735 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
1736{
1737 OSL_ASSERT(rpObject.is());
1738 OSL_ASSERT(::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)==maFocusableObjects.end());
1739
1740 maFocusableObjects.push_back(rpObject);
1741}
1742
1743void AccessibleFocusManager::RemoveFocusableObject (
1744 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
1745{
1746 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::iterator iObject (
1747 ::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject));
1748
1749 if (iObject != maFocusableObjects.end())
1750 maFocusableObjects.erase(iObject);
1751 else
1752 {
1753 OSL_ASSERT(m_isInDtor); // in dtor, was removed already
1754 }
1755}
1756
1757void AccessibleFocusManager::FocusObject (
1758 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
1759{
1760 // Remove the focus of any of the other focusable objects.
1761 for (auto& rxObject : maFocusableObjects)
1762 {
1763 if (rxObject!=rpObject)
1764 rxObject->SetIsFocused(false);
1765 }
1766
1767 if (rpObject.is())
1768 rpObject->SetIsFocused(true);
1769}
1770
1771} // end of namespace ::sd::presenter
1772
1773/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::vector< rtl::Reference< PresenterAccessible::AccessibleObject > > maFocusableObjects
bool m_isInDtor
::std::vector< AccessibleRelation > maRelations
static std::shared_ptr< AccessibleFocusManager > mpInstance
std::shared_ptr< PresenterTextView > mpTextView
rtl::Reference< PresenterController > mpPresenterController
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
std::vector< Reference< XAnimationNode > > maChildren
mutable::osl::Mutex m_aMutex
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override
virtual void SAL_CALL addAccessibleEventListener(const css::uno::Reference< css::accessibility::XAccessibleEventListener > &rxListener) override
css::uno::Reference< css::awt::XWindow2 > mxContentWindow
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint(const css::awt::Point &aPoint) override
void FireAccessibleEvent(const sal_Int16 nEventId, const css::uno::Any &rOldValue, const css::uno::Any &rNewValue)
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int64 nIndex) override
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
virtual css::awt::Point SAL_CALL getLocation() override
css::uno::Reference< css::accessibility::XAccessible > mxParentAccessible
virtual void SetWindow(const css::uno::Reference< css::awt::XWindow > &rxContentWindow, const css::uno::Reference< css::awt::XWindow > &rxBorderWindow)
virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point &aPoint) override
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
css::uno::Reference< css::awt::XWindow2 > mxBorderWindow
void AddChild(const ::rtl::Reference< AccessibleObject > &rpChild)
virtual void SAL_CALL windowResized(const css::awt::WindowEvent &rEvent) override
virtual void SAL_CALL windowHidden(const css::lang::EventObject &rEvent) override
AccessibleObject(css::lang::Locale aLocale, const sal_Int16 nRole, OUString sName)
void RemoveChild(const ::rtl::Reference< AccessibleObject > &rpChild)
virtual void SAL_CALL removeAccessibleEventListener(const css::uno::Reference< css::accessibility::XAccessibleEventListener > &rxListener) override
virtual css::awt::Rectangle SAL_CALL getBounds() override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
virtual void SAL_CALL windowMoved(const css::awt::WindowEvent &rEvent) override
virtual css::lang::Locale SAL_CALL getLocale() override
void UpdateState(const sal_Int64 aState, const bool bValue)
virtual bool GetWindowState(const sal_Int64 nType) const
void SetAccessibleParent(const css::uno::Reference< css::accessibility::XAccessible > &rxAccessibleParent)
virtual css::awt::Point SAL_CALL getLocationOnScreen() override
virtual void SAL_CALL windowShown(const css::lang::EventObject &rEvent) override
::std::vector< rtl::Reference< AccessibleObject > > maChildren
::std::vector< Reference< XAccessibleEventListener > > maListeners
virtual sal_Bool SAL_CALL setCaretPosition(sal_Int32 nIndex) override
AccessibleParagraph(const css::lang::Locale &rLocale, const OUString &rsName, SharedPresenterTextParagraph pParagraph, const sal_Int32 nParagraphIndex)
virtual sal_Int32 SAL_CALL getIndexAtPoint(const css::awt::Point &rPoint) override
virtual sal_Bool SAL_CALL scrollSubstringTo(sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override
virtual sal_Unicode SAL_CALL getCharacter(sal_Int32 nIndex) override
virtual sal_Bool SAL_CALL setSelection(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
virtual bool GetWindowState(const sal_Int64 nType) const override
virtual sal_Bool SAL_CALL copyText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes(::sal_Int32 nIndex, const css::uno::Sequence< OUString > &rRequestedAttributes) override
virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex(sal_Int32 nIndex, sal_Int16 nTextType) override
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 nTextType) override
virtual css::awt::Rectangle SAL_CALL getCharacterBounds(sal_Int32 nIndex) override
virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex(sal_Int32 nIndex, sal_Int16 nTextType) override
virtual OUString SAL_CALL getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
::rtl::Reference< AccessibleObject > mpAccessibleNotes
virtual void SAL_CALL focusGained(const css::awt::FocusEvent &rEvent) override
virtual void SAL_CALL focusLost(const css::awt::FocusEvent &rEvent) override
css::uno::Reference< css::awt::XWindow > mxPreviewBorderWindow
::rtl::Reference< PresenterController > mpPresenterController
virtual void SAL_CALL disposing() override
css::uno::Reference< css::drawing::framework::XPane2 > mxMainPane
css::uno::Reference< css::awt::XWindow > mxNotesContentWindow
css::uno::Reference< css::accessibility::XAccessible > mxAccessibleParent
css::uno::Reference< css::awt::XWindow > mxMainWindow
PresenterPaneContainer::SharedPaneDescriptor GetPreviewPane() const
PresenterAccessible(css::uno::Reference< css::uno::XComponentContext > xContext, ::rtl::Reference< PresenterController > xPresenterController, const css::uno::Reference< css::drawing::framework::XPane > &rxMainPane)
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &rArguments) override
css::uno::Reference< css::awt::XWindow > mxPreviewContentWindow
::rtl::Reference< AccessibleObject > mpAccessiblePreview
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override
css::uno::Reference< css::awt::XWindow > mxNotesBorderWindow
const css::uno::Reference< css::uno::XComponentContext > mxComponentContext
::rtl::Reference< AccessibleObject > mpAccessibleConsole
This class gives access to the configuration.
css::uno::Any GetConfigurationNode(const OUString &rsPathToNode)
Return a configuration node below the root of the called object.
A drawing framework view of the notes of a slide.
std::shared_ptr< PaneDescriptor > SharedPaneDescriptor
static constexpr OUStringLiteral msNotesPaneURL
static constexpr OUStringLiteral msCurrentSlidePreviewPaneURL
static constexpr OUStringLiteral msSlideSorterPaneURL
int nCount
EmbeddedObjectRef * pObject
sal_Int32 nState
OUString sName
std::mutex m_aMutex
sal_Int32 nIndex
#define SAL_INFO(area, stream)
@ Exception
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
::cppu::WeakComponentImplHelper< css::accessibility::XAccessible, css::lang::XInitialization, css::awt::XFocusListener > PresenterAccessibleInterfaceBase
std::shared_ptr< PresenterTextParagraph > SharedPresenterTextParagraph
QPRO_FUNC_TYPE nType
OUString msName
sal_Int16 mnParagraphIndex
unsigned char sal_Bool
sal_uInt16 sal_Unicode
@ VISIBLE
Definition: unolayer.hxx:37
UpdateState