desktop/qa/desktop_lib/test_desktop_lib.cxx | 4 desktop/source/lib/init.cxx | 17 + include/LibreOfficeKit/LibreOfficeKit.h | 3 include/sfx2/lokhelper.hxx | 2 include/sfx2/viewsh.hxx | 7 sfx2/source/view/lokhelper.cxx | 14 sfx2/source/view/viewsh.cxx | 410 ++++++++++++++++++++++++++++ 7 files changed, 454 insertions(+), 3 deletions(-)
New commits: commit 190f7caa9e5c565168a45fd198585526573d966d Author: Marco Cecchetti <[email protected]> AuthorDate: Thu Mar 23 08:33:16 2023 +0100 Commit: Marco Cecchetti <[email protected]> CommitDate: Fri May 5 08:55:06 2023 +0200 lok: accessibility event listener for focused paragraph LOKDocumentFocusListener keeps track of the currently focused paragraph. Change-Id: I0fa400694f3129608228ade0b96e0b4e0aee87e2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151363 Reviewed-by: Michael Meeks <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 3f5ca1f96fb4..55ef248ec932 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -3640,9 +3640,11 @@ void DesktopLOKTest::testABI() CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), offsetof(struct _LibreOfficeKitDocumentClass, getEditMode)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(68), offsetof(struct _LibreOfficeKitDocumentClass, setViewTimezone)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(69), + offsetof(struct _LibreOfficeKitDocumentClass, setAccessibilityState)); // As above - CPPUNIT_ASSERT_EQUAL(documentClassOffset(69), sizeof(struct _LibreOfficeKitDocumentClass)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(70), sizeof(struct _LibreOfficeKitDocumentClass)); } CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 949af11504ed..b3350be8e8aa 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1311,6 +1311,7 @@ static void doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const cha static void doc_setViewTimezone(LibreOfficeKitDocument* pThis, int nId, const char* timezone); +static void doc_setAccessibilityState(LibreOfficeKitDocument* pThis, int nId, bool bEnabled); } // extern "C" namespace { @@ -1460,6 +1461,8 @@ LibLODocument_Impl::LibLODocument_Impl(uno::Reference <css::lang::XComponent> xC m_pDocumentClass->setViewTimezone = doc_setViewTimezone; + m_pDocumentClass->setAccessibilityState = doc_setAccessibilityState; + gDocumentClass = m_pDocumentClass; } pClass = m_pDocumentClass.get(); @@ -6398,12 +6401,13 @@ static void doc_setViewLanguage(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*p SolarMutexGuard aGuard; SetLastExceptionMsg(); + SAL_DEBUG("doc_setViewLanguage: nId: " << nId); OUString sLanguage = OStringToOUString(language, RTL_TEXTENCODING_UTF8); SfxLokHelper::setViewLanguage(nId, sLanguage); SfxLokHelper::setViewLocale(nId, sLanguage); -} - + SfxLokHelper::setAccessibilityState(nId, true); +} unsigned char* doc_renderFont(LibreOfficeKitDocument* pThis, const char* pFontName, @@ -6946,6 +6950,15 @@ static void doc_setViewTimezone(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*p } } +static void doc_setAccessibilityState(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/, int nId, bool nEnabled) +{ + SolarMutexGuard aGuard; + if (gImpl) + gImpl->maLastExceptionMsg.clear(); + + SfxLokHelper::setAccessibilityState(nId, nEnabled); +} + static char* lo_getError (LibreOfficeKit *pThis) { comphelper::ProfileZone aZone("lo_getError"); diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index 767469666fef..30089bb11e0d 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -493,6 +493,9 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::setViewTimezone(). void (*setViewTimezone) (LibreOfficeKitDocument* pThis, int nId, const char* timezone); + /// @see lok::Document::setAccessibilityState(). + void (*setAccessibilityState) (LibreOfficeKitDocument* pThis, int nId, bool nEnabled); + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx index 184f899880f7..d2adacad55e6 100644 --- a/include/sfx2/lokhelper.hxx +++ b/include/sfx2/lokhelper.hxx @@ -83,6 +83,8 @@ public: static void setViewLanguage(int nId, const OUString& rBcp47LanguageTag); /// Set the default language for views. static void setDefaultLanguage(const OUString& rBcp47LanguageTag); + /// Enable/Disable AT support for the given view. + static void setAccessibilityState(int nId, bool nEnabled); /// Get the language used by the loading view (used for all save operations). static const LanguageTag & getLoadLanguage(); /// Set the language used by the loading view (used for all save operations). diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index c34e1a69640b..3b0bc9bdcaae 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -56,6 +56,7 @@ class SfxPrinter; class NotifyEvent; class SfxInPlaceClient; class SfxLokCallbackInterface; +class LOKDocumentFocusListener; class SfxStoringHelper; namespace rtl { class OStringBuffer; } namespace vcl { class PrinterController; } @@ -169,6 +170,8 @@ friend class SfxPrinterController; LanguageTag maLOKLanguageTag; LanguageTag maLOKLocale; LOKDeviceFormFactor maLOKDeviceFormFactor; + bool mbLOKAccessibilityEnabled; + std::unique_ptr<LOKDocumentFocusListener> mpLOKDocumentFocusListener; std::unordered_set<OUString> mvLOKBlockedCommandList; OUString maLOKTimezone; bool maLOKIsTimezoneSet; @@ -208,6 +211,8 @@ private: /// SfxInterface initializer. static void InitInterface_Impl(); + LOKDocumentFocusListener& GetLOKDocumentFocusListener(); + public: SfxViewShell( SfxViewFrame *pFrame, SfxViewShellFlags nFlags ); @@ -405,6 +410,8 @@ public: void SetLOKLanguageTag(const OUString& rBcp47LanguageTag); /// Get the LibreOfficeKit language of this view. const LanguageTag& GetLOKLanguageTag() const { return maLOKLanguageTag; } + /// Enable/Disable LibreOfficeKit AT support for this view. + void SetLOKAccessibilityState(bool bEnabled); /// Get the LibreOfficeKit timezone of this view. See @SetLOKTimezone. std::pair<bool, OUString> GetLOKTimezone() const diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index b66ad6d05b83..91c2e3830c99 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -314,6 +314,20 @@ void SfxLokHelper::setViewLanguage(int nId, const OUString& rBcp47LanguageTag) } } +void SfxLokHelper::setAccessibilityState(int nId, bool nEnabled) +{ + std::vector<SfxViewShell*>& rViewArr = SfxGetpApp()->GetViewShells_Impl(); + + for (SfxViewShell* pViewShell : rViewArr) + { + if (pViewShell->GetViewShellId() == ViewShellId(nId)) + { + pViewShell->SetLOKAccessibilityState(nEnabled); + return; + } + } +} + void SfxLokHelper::setViewLocale(int nId, const OUString& rBcp47LanguageTag) { std::vector<SfxViewShell*>& rViewArr = SfxGetpApp()->GetViewShells_Impl(); diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 9ae31f66e43e..221e41080562 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -46,9 +46,22 @@ #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> #include <com/sun/star/view/XRenderable.hpp> #include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> #include <cppuhelper/implbase.hxx> #include <com/sun/star/ui/XAcceleratorConfiguration.hpp> +#include <cppuhelper/weakref.hxx> + +#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> +#include <com/sun/star/accessibility/AccessibleTextType.hpp> +#include <com/sun/star/awt/FontSlant.hpp> + #include <comphelper/diagnose_ex.hxx> #include <tools/urlobj.hxx> #include <unotools/tempfile.hxx> @@ -220,6 +233,350 @@ void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::c delete pInfo; } +class LOKDocumentFocusListener : + public ::cppu::WeakImplHelper< accessibility::XAccessibleEventListener > +{ + + std::set< uno::Reference< uno::XInterface > > m_aRefList; + +public: + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + void attachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible + ); + + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + void attachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible, + const uno::Reference< accessibility::XAccessibleContext >& xContext + ); + + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + void attachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible, + const uno::Reference< accessibility::XAccessibleContext >& xContext, + const sal_Int64 nStateSet + ); + + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + void detachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible + ); + + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + void detachRecursive( + const uno::Reference< accessibility::XAccessibleContext >& xContext + ); + + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + void detachRecursive( + const uno::Reference< accessibility::XAccessibleContext >& xContext, + const sal_Int64 nStateSet + ); + + /// @throws lang::IndexOutOfBoundsException + /// @throws uno::RuntimeException + static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent ); + + // XEventListener + virtual void SAL_CALL disposing( const lang::EventObject& Source ) override; + + // XAccessibleEventListener + virtual void SAL_CALL notifyEvent( const accessibility::AccessibleEventObject& aEvent ) override; + +}; + +void LOKDocumentFocusListener::disposing( const lang::EventObject& aEvent ) +{ + + // Unref the object here, but do not remove as listener since the object + // might no longer be in a state that safely allows this. + if( aEvent.Source.is() ) + m_aRefList.erase(aEvent.Source); + +} + +void LOKDocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent ) +{ + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent:event id: " << aEvent.EventId); + try { + switch( aEvent.EventId ) + { + case accessibility::AccessibleEventId::STATE_CHANGED: + { + sal_Int16 nState = accessibility::AccessibleStateType::INVALID; + aEvent.NewValue >>= nState; + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: STATE_CHANGED: XAccessible: " << getAccessible(aEvent).get()); + + if( accessibility::AccessibleStateType::FOCUSED == nState ) + { + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: FOCUSED"); + + uno::Reference<css::accessibility::XAccessibleText> xAccText(getAccessible(aEvent), uno::UNO_QUERY); + if( xAccText.is() ) + { + OUString sText = xAccText->getText(); + sal_Int32 nLength = sText.getLength(); + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: xAccText: " << xAccText.get() << ", text: " << sText); + + if (nLength) + { + css::uno::Reference<css::accessibility::XAccessibleTextAttributes> xAccTextAttr(xAccText, uno::UNO_QUERY); + css::uno::Sequence< OUString > aRequestedAttributes; + + sal_Int32 nPos = 0; + while (nPos < nLength) + { + css::accessibility::TextSegment aTextSegment = + xAccText->getTextAtIndex(nPos, css::accessibility::AccessibleTextType::ATTRIBUTE_RUN); + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: text segment: '" << aTextSegment.SegmentText + << "', start: " << aTextSegment.SegmentStart << ", end: " << aTextSegment.SegmentEnd); + + css::uno::Sequence< css::beans::PropertyValue > aRunAttributeList; + if (xAccTextAttr.is()) + { + aRunAttributeList = xAccTextAttr->getRunAttributes(nPos, aRequestedAttributes); + } + else + { + aRunAttributeList = xAccText->getCharacterAttributes(nPos, aRequestedAttributes); + } + + sal_Int32 nSize = aRunAttributeList.getLength(); + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: attribute list size: " << nSize); + if (nSize) + { + OUString sValue; + OUString sAttributes = "{ "; + for (const auto& attribute: aRunAttributeList) + { + if (attribute.Name.isEmpty()) + continue; + + if (attribute.Name == "CharHeight" || attribute.Name == "CharWeight") + { + float fValue; + attribute.Value >>= fValue; + sValue = OUString::number(fValue); + } + else if (attribute.Name == "CharPosture") + { + awt::FontSlant nValue; + attribute.Value >>= nValue; + sValue = OUString::number((unsigned int)(nValue)); + } + else if (attribute.Name == "CharUnderline") + { + sal_Int16 nValue; + attribute.Value >>= nValue; + sValue = OUString::number(nValue); + } + else if (attribute.Name == "CharFontName") + { + attribute.Value >>= sValue; + } + else if (attribute.Name == "Rsid") + { + sal_uInt32 nValue; + attribute.Value >>= nValue; + sValue = OUString::number(nValue); + } + + if (!sValue.isEmpty()) + { + if (sAttributes != "{ ") + sAttributes += ", "; + sAttributes += attribute.Name + ": "; + sAttributes += sValue; + sValue = ""; + } + } + sAttributes += " }"; + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: attributes: " << sAttributes); + } + nPos = aTextSegment.SegmentEnd + 1; + } + } + + } + } + + break; + } + + case accessibility::AccessibleEventId::CHILD: + { + uno::Reference< accessibility::XAccessible > xChild; + if( (aEvent.OldValue >>= xChild) && xChild.is() ) + detachRecursive(xChild); + + if( (aEvent.NewValue >>= xChild) && xChild.is() ) + attachRecursive(xChild); + + break; + } + + case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN: + SAL_INFO("lok.a11y", "Invalidate all children called"); + break; + + default: + break; + } + } + catch( const lang::IndexOutOfBoundsException& e ) + { + SAL_WARN("lok.a11y", "Focused object has invalid index in parent"); + } +} + +uno::Reference< accessibility::XAccessible > LOKDocumentFocusListener::getAccessible(const lang::EventObject& aEvent ) +{ + uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY); + + if( xAccessible.is() ) + return xAccessible; + + uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY); + + if( xContext.is() ) + { + uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() ); + if( xParent.is() ) + { + uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); + if( xParentContext.is() ) + { + return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() ); + } + } + } + + return uno::Reference< accessibility::XAccessible >(); +} + +void LOKDocumentFocusListener::attachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible +) +{ + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(1): xAccessible: " << xAccessible.get()); + + uno::Reference< accessibility::XAccessibleContext > xContext = + xAccessible->getAccessibleContext(); + + if( xContext.is() ) + attachRecursive(xAccessible, xContext); +} + +void LOKDocumentFocusListener::attachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible, + const uno::Reference< accessibility::XAccessibleContext >& xContext +) +{ + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(2): xAccessible: " << xAccessible.get() + << ", role: " << xContext->getAccessibleRole() + << ", name: " << xContext->getAccessibleName() + << ", parent: " << xContext->getAccessibleParent().get() + << ", child count: " << xContext->getAccessibleChildCount()); + + sal_Int64 nStateSet = xContext->getAccessibleStateSet(); + + attachRecursive(xAccessible, xContext, nStateSet); +} + +void LOKDocumentFocusListener::attachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible, + const uno::Reference< accessibility::XAccessibleContext >& xContext, + const sal_Int64 nStateSet +) +{ + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(3) #1: this: " << this + << ", xAccessible: " << xAccessible.get() + << ", role: " << xContext->getAccessibleRole() + << ", name: " << xContext->getAccessibleName() + << ", parent: " << xContext->getAccessibleParent().get() + << ", child count: " << xContext->getAccessibleChildCount()); + + uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster = + uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY); + + if (!xBroadcaster.is()) + return; + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(3) #2: xBroadcaster.is()"); + // If not already done, add the broadcaster to the list and attach as listener. + const uno::Reference< uno::XInterface >& xInterface = xBroadcaster; + if( m_aRefList.insert(xInterface).second ) + { + SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(3) #3: m_aRefList.insert(xInterface).second"); + xBroadcaster->addAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); + + const sal_Int32 MAX_ATTACHABLE_CHILDREN = 10; + sal_Int32 n, nmax = xContext->getAccessibleChildCount(); + if( ( nStateSet & accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) && nmax > MAX_ATTACHABLE_CHILDREN ) + nmax = MAX_ATTACHABLE_CHILDREN; + + for( n = 0; n < nmax; n++ ) + { + uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); + + if( xChild.is() ) + attachRecursive(xChild); + } + } +} + +void LOKDocumentFocusListener::detachRecursive( + const uno::Reference< accessibility::XAccessible >& xAccessible +) +{ + uno::Reference< accessibility::XAccessibleContext > xContext = + xAccessible->getAccessibleContext(); + + if( xContext.is() ) + detachRecursive(xContext); +} + +void LOKDocumentFocusListener::detachRecursive( + const uno::Reference< accessibility::XAccessibleContext >& xContext +) +{ + sal_Int64 nStateSet = xContext->getAccessibleStateSet(); + + detachRecursive(xContext, nStateSet); +} + +void LOKDocumentFocusListener::detachRecursive( + const uno::Reference< accessibility::XAccessibleContext >& xContext, + const sal_Int64 nStateSet +) +{ + uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster = + uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY); + + if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) ) + { + xBroadcaster->removeAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); + + if( ( nStateSet & accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) == 0 ) + { + sal_Int32 n, nmax = xContext->getAccessibleChildCount(); + for( n = 0; n < nmax; n++ ) + { + uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); + + if( xChild.is() ) + detachRecursive(xChild); + } + } + } +} + sal_uInt32 SfxViewShell_Impl::m_nLastViewShellId = 0; SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags const nFlags, ViewShellDocId nDocId) @@ -1069,6 +1426,8 @@ SfxViewShell::SfxViewShell , maLOKLanguageTag(LANGUAGE_NONE) , maLOKLocale(LANGUAGE_NONE) , maLOKDeviceFormFactor(LOKDeviceFormFactor::UNKNOWN) +, mbLOKAccessibilityEnabled(false) +, mpLOKDocumentFocusListener(nullptr) { SetMargin( pViewFrame->GetMargin_Impl() ); @@ -1643,6 +2002,57 @@ void SfxViewShell::SetLOKLanguageTag(const OUString& rBcp47LanguageTag) maLOKLanguageTag = aFallbackTag; } +LOKDocumentFocusListener& SfxViewShell::GetLOKDocumentFocusListener() +{ + if (mpLOKDocumentFocusListener) + return *mpLOKDocumentFocusListener; + + mpLOKDocumentFocusListener.reset(new LOKDocumentFocusListener); + return *mpLOKDocumentFocusListener; +} + +void SfxViewShell::SetLOKAccessibilityState(bool bEnabled) +{ + if (bEnabled == mbLOKAccessibilityEnabled) + return; + mbLOKAccessibilityEnabled = bEnabled; + + SAL_DEBUG("SfxViewShell::SetLOKAccessibilityState: bEnabled: " << bEnabled); + LOKDocumentFocusListener& rDocumentFocusListener = GetLOKDocumentFocusListener(); + + if (!pWindow) + return; + + uno::Reference< accessibility::XAccessible > xAccessible = + pWindow->GetAccessible(); + + if (!xAccessible.is()) + return; + + if (mbLOKAccessibilityEnabled) + { + try + { + rDocumentFocusListener.attachRecursive(xAccessible); + } + catch (const uno::Exception&) + { + SAL_WARN("SetLOKAccessibilityState", "Exception caught processing LOKDocumentFocusListener::attachRecursive"); + } + } + else + { + try + { + rDocumentFocusListener.detachRecursive(xAccessible); + } + catch (const uno::Exception&) + { + SAL_WARN("SetLOKAccessibilityState", "Exception caught processing LOKDocumentFocusListener::detachRecursive"); + } + } +} + void SfxViewShell::SetLOKLocale(const OUString& rBcp47LanguageTag) { maLOKLocale = LanguageTag(rBcp47LanguageTag, true).makeFallback();
