diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2023-09-03 18:47:30 +0200 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2023-10-22 15:25:19 +0200 |
commit | 70cddea8cb780f2fe0acdd15b72d13ce2d1ad649 (patch) | |
tree | f4f249e184bde827a5634e2c3e8cc8053d69227d | |
parent | f1cb3bb7739b2917a2ba2bce45885bd20f6f7fba (diff) |
lok: a11y: send list item prefix length to client
Implemented getListPrefixSize function which relies on
UNO_NAME_NUMBERING_LEVEL, UNO_NAME_NUMBERING character attributes.
The former provides the list item level, the latter is a boolean that
says if a prefix (bullet/number) is present or not for the list item.
It has been needed to modify
SwAccessibleParagraph::_getSupplementalAttributesImpl so that it
returns such properties for list item only and not for simple
paragraph too. In fact for a simple paragraph the default value for
the level property was returned which is 0 exactly the same value for
top list item.
Change-Id: Ia651af4d4b2372eed42c90b0752e16fd47a4fdec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156816
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Gökay ŞATIR <gokaysatir@collabora.com>
(cherry picked from commit 038903d2e066de9525a3baffdd232484ef44ff51)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157780
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKitEnums.h | 2 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 74 | ||||
-rw-r--r-- | sw/source/core/access/accpara.cxx | 14 | ||||
-rw-r--r-- | sw/source/core/unocore/unomapproperties.hxx | 1 |
4 files changed, 86 insertions, 5 deletions
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index e7f31c2a14fe..883a68ce09c6 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -932,9 +932,11 @@ typedef enum * "position": N * "start": N1 * "end": N2 + * "listPrefixLength": L * } * where N is the position of the text cursor inside the focused paragraph, * and [N1,N2] is the range of the text selection inside the focused paragraph. + * In case the paragraph is a list item, L is the length of the bullet/number prefix. */ LOK_CALLBACK_A11Y_FOCUS_CHANGED = 62, diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 5e437b45269a..68c99691fb4c 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -67,6 +67,7 @@ #include <com/sun/star/awt/FontSlant.hpp> #include <comphelper/diagnose_ex.hxx> +#include <editeng/unoprnms.hxx> #include <tools/urlobj.hxx> #include <unotools/tempfile.hxx> #include <svtools/soerr.hxx> @@ -409,6 +410,42 @@ void aboutEvent(std::string msg, const accessibility::AccessibleEventObject& aEv } } +sal_Int32 getListPrefixSize(const uno::Reference<css::accessibility::XAccessibleText>& xAccText) +{ + if (!xAccText.is()) + return 0; + + OUString sText = xAccText->getText(); + sal_Int32 nLength = sText.getLength(); + if (nLength <= 0) + return 0; + + css::uno::Sequence< css::beans::PropertyValue > aRunAttributeList; + css::uno::Sequence< OUString > aRequestedAttributes = {UNO_NAME_NUMBERING_LEVEL, UNO_NAME_NUMBERING}; + aRunAttributeList = xAccText->getCharacterAttributes(0, aRequestedAttributes); + + sal_Int16 nLevel = -1; + bool bIsCounted = false; + for (const auto& attribute: aRunAttributeList) + { + if (attribute.Name.isEmpty()) + continue; + if (attribute.Name == UNO_NAME_NUMBERING_LEVEL) + attribute.Value >>= nLevel; + else if (attribute.Name == UNO_NAME_NUMBERING) + attribute.Value >>= bIsCounted; + } + if (nLevel < 0 || !bIsCounted) + return 0; + + css::accessibility::TextSegment aTextSegment = + xAccText->getTextAtIndex(0, css::accessibility::AccessibleTextType::ATTRIBUTE_RUN); + + SAL_INFO("lok.a11y", "getListPrefixSize: prefix: " << aTextSegment.SegmentText << ", level: " << nLevel); + + return aTextSegment.SegmentEnd; +} + void aboutTextFormatting(std::string msg, const uno::Reference<css::accessibility::XAccessibleText>& xAccText) { if (!xAccText.is()) @@ -483,6 +520,22 @@ void aboutTextFormatting(std::string msg, const uno::Reference<css::accessibilit attribute.Value >>= nValue; sValue = OUString::number(nValue); } + else if (attribute.Name == UNO_NAME_NUMBERING_LEVEL) + { + sal_Int16 nValue(-1); + attribute.Value >>= nValue; + sValue = OUString::number(nValue); + } + else if (attribute.Name == UNO_NAME_NUMBERING) + { + bool bValue(false); + attribute.Value >>= bValue; + sValue = OUString::boolean(bValue); + } + else if (attribute.Name == UNO_NAME_NUMBERING_RULES) + { + attribute.Value >>= sValue; + } if (!sValue.isEmpty()) { @@ -501,12 +554,14 @@ void aboutTextFormatting(std::string msg, const uno::Reference<css::accessibilit } void aboutParagraph(std::string msg, const OUString& rsParagraphContent, sal_Int32 nCaretPosition, - sal_Int32 nSelectionStart, sal_Int32 nSelectionEnd, bool force = false) + sal_Int32 nSelectionStart, sal_Int32 nSelectionEnd, sal_Int32 nListPrefixLength, + bool force = false) { SAL_INFO("lok.a11y", msg << ": " "\n text content: \"" << rsParagraphContent << "\"" "\n caret pos: " << nCaretPosition << "\n selection: start: " << nSelectionStart << ", end: " << nSelectionEnd + << "\n list prefix length: " << nListPrefixLength << "\n force: " << force ); } @@ -521,7 +576,8 @@ void aboutParagraph(std::string msg, const uno::Reference<css::accessibility::XA sal_Int32 nCaretPosition = xAccText->getCaretPosition(); sal_Int32 nSelectionStart = xAccText->getSelectionStart(); sal_Int32 nSelectionEnd = xAccText->getSelectionEnd(); - aboutParagraph(msg, sText, nCaretPosition, nSelectionStart, nSelectionEnd, force); + sal_Int32 nListPrefixLength = getListPrefixSize(xAccText); + aboutParagraph(msg, sText, nCaretPosition, nSelectionStart, nSelectionEnd, nListPrefixLength, force); } void aboutFocusedCellChanged(sal_Int32 nOutCount, const std::vector<TableSizeType>& aInList, @@ -557,6 +613,7 @@ class LOKDocumentFocusListener : sal_Int32 m_nCaretPosition; sal_Int32 m_nSelectionStart; sal_Int32 m_nSelectionEnd; + sal_Int32 m_nListPrefixLength; uno::Reference<accessibility::XAccessibleTable> m_xLastTable; OUString m_sSelectedText; bool m_bIsEditingCell; @@ -640,6 +697,7 @@ LOKDocumentFocusListener::LOKDocumentFocusListener(const SfxViewShell* pViewShel , m_nCaretPosition(0) , m_nSelectionStart(0) , m_nSelectionEnd(0) + , m_nListPrefixLength(0) , m_bIsEditingCell(false) { } @@ -651,6 +709,8 @@ void LOKDocumentFocusListener::paragraphPropertiesToTree(boost::property_tree::p aPayloadTree.put("position", m_nCaretPosition); aPayloadTree.put("start", bLeftToRight ? m_nSelectionStart : m_nSelectionEnd); aPayloadTree.put("end", bLeftToRight ? m_nSelectionEnd : m_nSelectionStart); + if (m_nListPrefixLength > 0) + aPayloadTree.put("listPrefixLength", m_nListPrefixLength); if (force) aPayloadTree.put("force", 1); } @@ -668,7 +728,8 @@ OUString LOKDocumentFocusListener::getFocusedParagraph() const { aboutView("LOKDocumentFocusListener::getFocusedParagraph", this, m_pViewShell); aboutParagraph("LOKDocumentFocusListener::getFocusedParagraph", - m_sFocusedParagraph, m_nCaretPosition, m_nSelectionStart, m_nSelectionEnd); + m_sFocusedParagraph, m_nCaretPosition, + m_nSelectionStart, m_nSelectionEnd, m_nListPrefixLength); std::string aPayload; paragraphPropertiesToJson(aPayload); @@ -710,7 +771,8 @@ void LOKDocumentFocusListener::notifyFocusedParagraphChanged(bool force) if (m_pViewShell) { aboutParagraph("LOKDocumentFocusListener::notifyFocusedParagraphChanged", - m_sFocusedParagraph, m_nCaretPosition, m_nSelectionStart, m_nSelectionEnd, force); + m_sFocusedParagraph, m_nCaretPosition, + m_nSelectionStart, m_nSelectionEnd, m_nListPrefixLength, force); m_pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_A11Y_FOCUS_CHANGED, aPayload.c_str()); } @@ -796,7 +858,8 @@ void LOKDocumentFocusListener::notifyFocusedCellChanged( { aboutFocusedCellChanged(nOutCount, aInList, nRow, nCol, nRowSpan, nColSpan); aboutParagraph("LOKDocumentFocusListener::notifyFocusedCellChanged: paragraph: ", - m_sFocusedParagraph, m_nCaretPosition, m_nSelectionStart, m_nSelectionEnd, false); + m_sFocusedParagraph, m_nCaretPosition, m_nSelectionStart, + m_nSelectionEnd, m_nListPrefixLength, false); m_pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_A11Y_FOCUSED_CELL_CHANGED, aPayload.c_str()); } @@ -826,6 +889,7 @@ bool LOKDocumentFocusListener::updateParagraphInfo(const uno::Reference<css::acc m_nCaretPosition = nCaretPosition; m_nSelectionStart = xAccText->getSelectionStart(); m_nSelectionEnd = xAccText->getSelectionEnd(); + m_nListPrefixLength = getListPrefixSize(xAccText); // In case only caret position or text selection are different we can rely on specific events. if (m_sFocusedParagraph != sText) diff --git a/sw/source/core/access/accpara.cxx b/sw/source/core/access/accpara.cxx index 7226ea72d35d..96e58f35f1c3 100644 --- a/sw/source/core/access/accpara.cxx +++ b/sw/source/core/access/accpara.cxx @@ -910,6 +910,7 @@ static uno::Sequence< OUString > const & getSupplementalAttributeNames() { // sorted list of strings UNO_NAME_NUMBERING_LEVEL, + UNO_NAME_NUMBERING, UNO_NAME_NUMBERING_RULES, UNO_NAME_PARA_ADJUST, UNO_NAME_PARA_BOTTOM_MARGIN, @@ -1360,6 +1361,9 @@ uno::Sequence<PropertyValue> SwAccessibleParagraph::getCharacterAttributes( tAccParaPropValMap aRunAttrSeq; _getRunAttributesImpl( nIndex, aNames, aRunAttrSeq ); + // this allows to request one or more supplemental attributes, only + bSupplementalMode = bSupplementalMode || aDefAttrSeq.empty() || aRunAttrSeq.empty(); + // merge default and run attributes std::vector< PropertyValue > aValues( aDefAttrSeq.size() ); sal_Int32 i = 0; @@ -1765,6 +1769,7 @@ void SwAccessibleParagraph::_getSupplementalAttributesImpl( if ( pTextNode->HasBullet() || pTextNode->HasNumber() ) { aSet.Put( pTextNode->GetAttr(RES_PARATR_LIST_LEVEL) ); + aSet.Put( pTextNode->GetAttr(RES_PARATR_LIST_ISCOUNTED) ); } aSet.Put( pTextNode->SwContentNode::GetAttr(RES_UL_SPACE) ); aSet.Put( pTextNode->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE) ); @@ -1778,6 +1783,15 @@ void SwAccessibleParagraph::_getSupplementalAttributesImpl( aSwMapProvider.GetPropertyMapEntries( PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE ) ); for (const auto & rEntry : pPropMap) { + // For a paragraph, list level property is not set but when queried the returned default + // value is 0, exactly the same value of top level list item; that prevents using + // list level property for discerning simple paragraph from list item; + // the following check allows not to return the list level property at all + // when we are dealing with a simple paragraph + if ((rEntry.nWID == RES_PARATR_LIST_LEVEL || rEntry.nWID == RES_PARATR_LIST_ISCOUNTED) && + !aSet.HasItem( rEntry.nWID )) + continue; + const SfxPoolItem* pItem = aSet.GetItem( rEntry.nWID ); if ( pItem ) { diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx index 323aa3b9ce46..2330ba8608e6 100644 --- a/sw/source/core/unocore/unomapproperties.hxx +++ b/sw/source/core/unocore/unomapproperties.hxx @@ -533,6 +533,7 @@ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR}, \ { UNO_NAME_CHAR_WEIGHT, RES_CHRATR_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \ { UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \ + { UNO_NAME_NUMBERING, RES_PARATR_LIST_ISCOUNTED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0}, \ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE}, \ { UNO_NAME_NUMBERING_RULES, RES_PARATR_NUMRULE,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \ { UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST}, \ |