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 038903d2e0
)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157780
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
This commit is contained in:
parent
f1cb3bb773
commit
70cddea8cb
4 changed files with 86 additions and 5 deletions
|
@ -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,
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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}, \
|
||||
|
|
Loading…
Reference in a new issue