summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2023-09-03 18:47:30 +0200
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-10-22 15:25:19 +0200
commit70cddea8cb780f2fe0acdd15b72d13ce2d1ad649 (patch)
treef4f249e184bde827a5634e2c3e8cc8053d69227d
parentf1cb3bb7739b2917a2ba2bce45885bd20f6f7fba (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.h2
-rw-r--r--sfx2/source/view/viewsh.cxx74
-rw-r--r--sw/source/core/access/accpara.cxx14
-rw-r--r--sw/source/core/unocore/unomapproperties.hxx1
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}, \