sd/Library_sdui.mk | 1 sd/source/console/AccessibleNotes.cxx | 166 +++++++++++++++++++++++++++ sd/source/console/AccessibleNotes.hxx | 56 +++++++++ sd/source/console/AccessibleObject.cxx | 4 sd/source/console/AccessibleObject.hxx | 2 sd/source/console/AccessibleParagraph.cxx | 3 sd/source/console/AccessibleParagraph.hxx | 1 sd/source/console/PresenterAccessibility.cxx | 161 -------------------------- sd/source/console/PresenterController.cxx | 17 +- solenv/clang-format/excludelist | 1 10 files changed, 236 insertions(+), 176 deletions(-)
New commits: commit 97981695a9bf3b7922733f5021cd4c8b9578efe2 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed May 14 11:35:05 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu May 15 06:49:34 2025 +0200 sd a11y: Move AccessibleNotes to own .hxx/.cxx Change-Id: I47e79a6e568edd8301ebc2e67606b67b31d0a017 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185314 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/sd/Library_sdui.mk b/sd/Library_sdui.mk index 8c4b97954a10..48cdaca3d159 100644 --- a/sd/Library_sdui.mk +++ b/sd/Library_sdui.mk @@ -92,6 +92,7 @@ $(eval $(call gb_Library_add_exception_objects,sdui,\ sd/source/ui/dlg/PhotoAlbumDialog \ sd/source/ui/dlg/BulletAndPositionDlg \ sd/source/console/AccessibleFocusManager \ + sd/source/console/AccessibleNotes \ sd/source/console/AccessibleObject \ sd/source/console/AccessibleParagraph \ sd/source/console/PresenterAccessibility \ diff --git a/sd/source/console/AccessibleNotes.cxx b/sd/source/console/AccessibleNotes.cxx new file mode 100644 index 000000000000..b17fe7883b17 --- /dev/null +++ b/sd/source/console/AccessibleNotes.cxx @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "AccessibleFocusManager.hxx" +#include "AccessibleNotes.hxx" +#include "PresenterAccessibility.hxx" +#include "PresenterTextView.hxx" + +#include <strings.hrc> +#include <sdresid.hxx> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> + + +namespace sdext::presenter { + +AccessibleNotes::AccessibleNotes(const OUString& rsName) + : AccessibleObject(AccessibleRole::PANEL, rsName) +{ +} + +rtl::Reference<AccessibleObject> AccessibleNotes::Create( + const Reference<awt::XWindow>& rxContentWindow, + const Reference<awt::XWindow>& rxBorderWindow, + const std::shared_ptr<PresenterTextView>& rpTextView) +{ + const OUString sName = SdResId(STR_A11Y_PRESENTER_NOTES); + rtl::Reference<AccessibleNotes> pObject ( + new AccessibleNotes(sName)); + pObject->LateInitialization(); + pObject->SetTextView(rpTextView); + pObject->UpdateStateSet(); + pObject->SetWindow(rxContentWindow, rxBorderWindow); + + return pObject; +} + +void AccessibleNotes::SetTextView ( + const std::shared_ptr<PresenterTextView>& rpTextView) +{ + ::std::vector<rtl::Reference<AccessibleObject> > aChildren; + + // Release any listeners to the current text view. + if (mpTextView) + { + mpTextView->GetCaret()->SetCaretMotionBroadcaster( + ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)>()); + mpTextView->SetTextChangeBroadcaster( + ::std::function<void ()>()); + } + + mpTextView = rpTextView; + + if (!mpTextView) + return; + + // Create a new set of children, one for each paragraph. + const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount()); + for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex) + { + rtl::Reference<AccessibleParagraph> pParagraph ( + new AccessibleParagraph( + rpTextView->GetParagraph(nIndex), + nIndex)); + pParagraph->LateInitialization(); + pParagraph->SetWindow(mxContentWindow, mxBorderWindow); + pParagraph->SetAccessibleParent(this); + aChildren.emplace_back(pParagraph.get()); + } + maChildren.swap(aChildren); + FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); + + // Dispose the old children. (This will remove them from the focus + // manager). + for (const auto& rxChild : aChildren) + { + if (rxChild.is()) + rxChild->dispose(); + } + + // This class acts as a controller of who broadcasts caret motion + // events and handles text changes. Register the corresponding + // listeners here. + mpTextView->GetCaret()->SetCaretMotionBroadcaster( + [this](sal_Int32 a, sal_Int32 b, sal_Int32 c, sal_Int32 d) + { return this->NotifyCaretChange(a, b, c, d); }); + mpTextView->SetTextChangeBroadcaster( + [this]() { return SetTextView(mpTextView); }); +} + +void AccessibleNotes::SetWindow ( + const css::uno::Reference<css::awt::XWindow>& rxContentWindow, + const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) +{ + AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow); + + // Set the windows at the children as well, so that every paragraph can + // setup its geometry. + for (auto& rxChild : maChildren) + { + rxChild->SetWindow(rxContentWindow, rxBorderWindow); + } +} + +void AccessibleNotes::NotifyCaretChange ( + const sal_Int32 nOldParagraphIndex, + const sal_Int32 nOldCharacterIndex, + const sal_Int32 nNewParagraphIndex, + const sal_Int32 nNewCharacterIndex) +{ + AccessibleFocusManager::Instance()->FocusObject( + nNewParagraphIndex >= 0 + ? maChildren[nNewParagraphIndex] + : this); + + if (nOldParagraphIndex != nNewParagraphIndex) + { + // Moved caret from one paragraph to another (or showed or + // hid the caret). Move focus from one accessible + // paragraph to another. + if (nOldParagraphIndex >= 0) + { + maChildren[nOldParagraphIndex]->FireAccessibleEvent( + AccessibleEventId::CARET_CHANGED, + Any(nOldCharacterIndex), + Any(sal_Int32(-1))); + } + if (nNewParagraphIndex >= 0) + { + maChildren[nNewParagraphIndex]->FireAccessibleEvent( + AccessibleEventId::CARET_CHANGED, + Any(sal_Int32(-1)), + Any(nNewCharacterIndex)); + } + } + else if (nNewParagraphIndex >= 0) + { + // Caret moved inside one paragraph. + maChildren[nNewParagraphIndex]->FireAccessibleEvent( + AccessibleEventId::CARET_CHANGED, + Any(nOldCharacterIndex), + Any(nNewCharacterIndex)); + } +} + +} // end of namespace ::sd::presenter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sd/source/console/AccessibleNotes.hxx b/sd/source/console/AccessibleNotes.hxx new file mode 100644 index 000000000000..be8adec3943d --- /dev/null +++ b/sd/source/console/AccessibleNotes.hxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include "AccessibleObject.hxx" + +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <rtl/ref.hxx> + +namespace sdext::presenter +{ +class PresenterTextView; + +class AccessibleNotes : public AccessibleObject +{ +public: + AccessibleNotes(const OUString& rsName); + + static rtl::Reference<AccessibleObject> + Create(const css::uno::Reference<awt::XWindow>& rxContentWindow, + const css::uno::Reference<awt::XWindow>& rxBorderWindow, + const std::shared_ptr<PresenterTextView>& rpTextView); + + void SetTextView(const std::shared_ptr<PresenterTextView>& rpTextView); + + virtual void SetWindow(const css::uno::Reference<css::awt::XWindow>& rxContentWindow, + const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) override; + +private: + std::shared_ptr<PresenterTextView> mpTextView; + + void NotifyCaretChange(const sal_Int32 nOldParagraphIndex, const sal_Int32 nOldCharacterIndex, + const sal_Int32 nNewParagraphIndex, const sal_Int32 nNewCharacterIndex); +}; + +} // end of namespace ::sd::presenter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sd/source/console/PresenterAccessibility.cxx b/sd/source/console/PresenterAccessibility.cxx index c4016e11c9e7..8ede63632980 100644 --- a/sd/source/console/PresenterAccessibility.cxx +++ b/sd/source/console/PresenterAccessibility.cxx @@ -18,6 +18,7 @@ */ #include "AccessibleFocusManager.hxx" +#include "AccessibleNotes.hxx" #include "PresenterAccessibility.hxx" #include "PresenterTextView.hxx" #include "PresenterNotesView.hxx" @@ -79,34 +80,6 @@ public: } }; -//===== AccessibleNotes ======================================================= - -class AccessibleNotes : public AccessibleObject -{ -public: - AccessibleNotes(const OUString& rsName); - - static rtl::Reference<AccessibleObject> Create( - const Reference<awt::XWindow>& rxContentWindow, - const Reference<awt::XWindow>& rxBorderWindow, - const std::shared_ptr<PresenterTextView>& rpTextView); - - void SetTextView (const std::shared_ptr<PresenterTextView>& rpTextView); - - virtual void SetWindow ( - const css::uno::Reference<css::awt::XWindow>& rxContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) override; - -private: - std::shared_ptr<PresenterTextView> mpTextView; - - void NotifyCaretChange ( - const sal_Int32 nOldParagraphIndex, - const sal_Int32 nOldCharacterIndex, - const sal_Int32 nNewParagraphIndex, - const sal_Int32 nNewCharacterIndex); -}; - } //===== PresenterAccessible =================================================== @@ -363,137 +336,6 @@ void SAL_CALL PresenterAccessible::initialize (const css::uno::Sequence<css::uno } } -//===== AccessibleNotes ======================================================= - -AccessibleNotes::AccessibleNotes(const OUString& rsName) - : AccessibleObject(AccessibleRole::PANEL, rsName) -{ -} - -rtl::Reference<AccessibleObject> AccessibleNotes::Create( - const Reference<awt::XWindow>& rxContentWindow, - const Reference<awt::XWindow>& rxBorderWindow, - const std::shared_ptr<PresenterTextView>& rpTextView) -{ - const OUString sName = SdResId(STR_A11Y_PRESENTER_NOTES); - rtl::Reference<AccessibleNotes> pObject ( - new AccessibleNotes(sName)); - pObject->LateInitialization(); - pObject->SetTextView(rpTextView); - pObject->UpdateStateSet(); - pObject->SetWindow(rxContentWindow, rxBorderWindow); - - return pObject; -} - -void AccessibleNotes::SetTextView ( - const std::shared_ptr<PresenterTextView>& rpTextView) -{ - ::std::vector<rtl::Reference<AccessibleObject> > aChildren; - - // Release any listeners to the current text view. - if (mpTextView) - { - mpTextView->GetCaret()->SetCaretMotionBroadcaster( - ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)>()); - mpTextView->SetTextChangeBroadcaster( - ::std::function<void ()>()); - } - - mpTextView = rpTextView; - - if (!mpTextView) - return; - - // Create a new set of children, one for each paragraph. - const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount()); - for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex) - { - rtl::Reference<AccessibleParagraph> pParagraph ( - new AccessibleParagraph( - rpTextView->GetParagraph(nIndex), - nIndex)); - pParagraph->LateInitialization(); - pParagraph->SetWindow(mxContentWindow, mxBorderWindow); - pParagraph->SetAccessibleParent(this); - aChildren.emplace_back(pParagraph.get()); - } - maChildren.swap(aChildren); - FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); - - // Dispose the old children. (This will remove them from the focus - // manager). - for (const auto& rxChild : aChildren) - { - if (rxChild.is()) - rxChild->dispose(); - } - - // This class acts as a controller of who broadcasts caret motion - // events and handles text changes. Register the corresponding - // listeners here. - mpTextView->GetCaret()->SetCaretMotionBroadcaster( - [this](sal_Int32 a, sal_Int32 b, sal_Int32 c, sal_Int32 d) - { return this->NotifyCaretChange(a, b, c, d); }); - mpTextView->SetTextChangeBroadcaster( - [this]() { return SetTextView(mpTextView); }); -} - -void AccessibleNotes::SetWindow ( - const css::uno::Reference<css::awt::XWindow>& rxContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) -{ - AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow); - - // Set the windows at the children as well, so that every paragraph can - // setup its geometry. - for (auto& rxChild : maChildren) - { - rxChild->SetWindow(rxContentWindow, rxBorderWindow); - } -} - -void AccessibleNotes::NotifyCaretChange ( - const sal_Int32 nOldParagraphIndex, - const sal_Int32 nOldCharacterIndex, - const sal_Int32 nNewParagraphIndex, - const sal_Int32 nNewCharacterIndex) -{ - AccessibleFocusManager::Instance()->FocusObject( - nNewParagraphIndex >= 0 - ? maChildren[nNewParagraphIndex] - : this); - - if (nOldParagraphIndex != nNewParagraphIndex) - { - // Moved caret from one paragraph to another (or showed or - // hid the caret). Move focus from one accessible - // paragraph to another. - if (nOldParagraphIndex >= 0) - { - maChildren[nOldParagraphIndex]->FireAccessibleEvent( - AccessibleEventId::CARET_CHANGED, - Any(nOldCharacterIndex), - Any(sal_Int32(-1))); - } - if (nNewParagraphIndex >= 0) - { - maChildren[nNewParagraphIndex]->FireAccessibleEvent( - AccessibleEventId::CARET_CHANGED, - Any(sal_Int32(-1)), - Any(nNewCharacterIndex)); - } - } - else if (nNewParagraphIndex >= 0) - { - // Caret moved inside one paragraph. - maChildren[nNewParagraphIndex]->FireAccessibleEvent( - AccessibleEventId::CARET_CHANGED, - Any(nOldCharacterIndex), - Any(nNewCharacterIndex)); - } -} - } // end of namespace ::sd::presenter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index 52dbb3e2f2a8..11409783e3d3 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -9252,6 +9252,7 @@ sd/qa/unit/tiledrendering/tiledrendering.cxx sd/qa/unit/uimpress.cxx sd/source/console/AccessibleFocusManager.cxx sd/source/console/AccessibleFocusManager.hxx +sd/source/console/AccessibleNotes.cxx sd/source/console/AccessibleObject.cxx sd/source/console/AccessibleObject.hxx sd/source/console/AccessibleParagraph.cxx commit 2995ba081fd969dae0a02177face830b001ff11c Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed May 14 11:14:22 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu May 15 06:49:27 2025 +0200 sd a11y: Don't set a11y name for notes paragraph Stop setting an accessible name for paragraphs in Impress Presenter Console notes. This is consistent with no names being used elsewhere (like Writer paragraphs) and matches also with the W3C ARIA "Providing Accessible Names and Descriptions" guideline [1], section "Accessible Name Guidance by Role" that says "Necessity of Naming: Prohibited" for the paragraph role. [1] https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/#accessiblenameguidancebyrole Change-Id: I0d87e3bf38cc1128eea493e76f9efcd7f5df8c0d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185313 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/sd/source/console/AccessibleObject.cxx b/sd/source/console/AccessibleObject.cxx index bae9616b572f..05cb5de35cc4 100644 --- a/sd/source/console/AccessibleObject.cxx +++ b/sd/source/console/AccessibleObject.cxx @@ -28,8 +28,8 @@ AccessibleObject::AccessibleObject( const sal_Int16 nRole, - OUString sName) - : msName(std::move(sName)), + const OUString& rName) + : msName(rName), mnRole(nRole), mnStateSet(0), mbIsFocused(false) diff --git a/sd/source/console/AccessibleObject.hxx b/sd/source/console/AccessibleObject.hxx index 40f86846f28e..8718de1aa1fd 100644 --- a/sd/source/console/AccessibleObject.hxx +++ b/sd/source/console/AccessibleObject.hxx @@ -41,7 +41,7 @@ class AccessibleObject css::accessibility::XAccessible, css::awt::XWindowListener> { public: - AccessibleObject(const sal_Int16 nRole, OUString sName); + AccessibleObject(const sal_Int16 nRole, const OUString& rName = OUString()); void LateInitialization(); virtual void SetWindow ( diff --git a/sd/source/console/AccessibleParagraph.cxx b/sd/source/console/AccessibleParagraph.cxx index eb39f89f5c3f..37c9afc7c1ee 100644 --- a/sd/source/console/AccessibleParagraph.cxx +++ b/sd/source/console/AccessibleParagraph.cxx @@ -110,10 +110,9 @@ AccessibleRelation SAL_CALL AccessibleRelationSet::getRelationByType(AccessibleR AccessibleParagraph::AccessibleParagraph( - const OUString& rsName, SharedPresenterTextParagraph xParagraph, const sal_Int32 nParagraphIndex) - : PresenterAccessibleParagraphInterfaceBase(AccessibleRole::PARAGRAPH, rsName), + : PresenterAccessibleParagraphInterfaceBase(AccessibleRole::PARAGRAPH), mpParagraph(std::move(xParagraph)), mnParagraphIndex(nParagraphIndex) { diff --git a/sd/source/console/AccessibleParagraph.hxx b/sd/source/console/AccessibleParagraph.hxx index 12ac77315477..6860b1e1465e 100644 --- a/sd/source/console/AccessibleParagraph.hxx +++ b/sd/source/console/AccessibleParagraph.hxx @@ -43,7 +43,6 @@ class AccessibleParagraph { public: AccessibleParagraph( - const OUString& rsName, SharedPresenterTextParagraph pParagraph, const sal_Int32 nParagraphIndex); diff --git a/sd/source/console/PresenterAccessibility.cxx b/sd/source/console/PresenterAccessibility.cxx index a809f5bbb4e5..c4016e11c9e7 100644 --- a/sd/source/console/PresenterAccessibility.cxx +++ b/sd/source/console/PresenterAccessibility.cxx @@ -411,7 +411,6 @@ void AccessibleNotes::SetTextView ( { rtl::Reference<AccessibleParagraph> pParagraph ( new AccessibleParagraph( - "Paragraph"+OUString::number(nIndex), rpTextView->GetParagraph(nIndex), nIndex)); pParagraph->LateInitialization(); commit 60d673bfbde05ddb0b0aab68906ab5409131f8ad Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed May 14 00:37:23 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu May 15 06:49:19 2025 +0200 sd: Drop superfluous check There's already a check for mxSlideShowController being non-null further up, and an exception is thrown if it isn't, so this code path wouldn't be reached in that case. Change-Id: Ia34a762d331af45b3d59384490ba7c9fd377f4fc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185291 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/sd/source/console/PresenterController.cxx b/sd/source/console/PresenterController.cxx index 561f6015828d..ab612f95f0b3 100644 --- a/sd/source/console/PresenterController.cxx +++ b/sd/source/console/PresenterController.cxx @@ -140,17 +140,14 @@ PresenterController::PresenterController ( mpPaneBorderPainter = new PresenterPaneBorderPainter(rxContext); mpWindowManager->SetPaneBorderPainter(mpPaneBorderPainter); - if (mxSlideShowController.is()) + mxSlideShowController->activate(); + Reference<beans::XPropertySet> xProperties (mxSlideShowController, UNO_QUERY); + if (xProperties.is()) { - mxSlideShowController->activate(); - Reference<beans::XPropertySet> xProperties (mxSlideShowController, UNO_QUERY); - if (xProperties.is()) - { - Reference<awt::XWindow> xWindow ( - xProperties->getPropertyValue(u"ParentWindow"_ustr), UNO_QUERY); - if (xWindow.is()) - xWindow->addKeyListener(this); - } + Reference<awt::XWindow> xWindow ( + xProperties->getPropertyValue(u"ParentWindow"_ustr), UNO_QUERY); + if (xWindow.is()) + xWindow->addKeyListener(this); } UpdateCurrentSlide(0);