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 #include +#include #include #include #include @@ -409,6 +410,42 @@ void aboutEvent(std::string msg, const accessibility::AccessibleEventObject& aEv } } +sal_Int32 getListPrefixSize(const uno::Reference& 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& xAccText) { if (!xAccText.is()) @@ -483,6 +520,22 @@ void aboutTextFormatting(std::string msg, const uno::Reference>= 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::ReferencegetCaretPosition(); 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& 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 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::ReferencegetSelectionStart(); 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 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::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR}, \ { UNO_NAME_CHAR_WEIGHT, RES_CHRATR_WEIGHT , cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \ { UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL,cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, 0}, \ + { UNO_NAME_NUMBERING, RES_PARATR_LIST_ISCOUNTED, cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, 0}, \ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE , cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE}, \ { UNO_NAME_NUMBERING_RULES, RES_PARATR_NUMRULE,cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \ { UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST}, \