fixed #15521: Fixed an accessibility for list view item
This commit is contained in:
parent
186dbacf08
commit
18fcb367db
|
@ -368,6 +368,12 @@ int AccessibleItem::accessibleCharacterCount() const
|
||||||
return static_cast<int>(text->plainText().size());
|
return static_cast<int>(text->plainText().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AccessibleItem::accessibleRowIndex() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool AccessibleItem::accessibleState(State st) const
|
bool AccessibleItem::accessibleState(State st) const
|
||||||
{
|
{
|
||||||
if (!registered()) {
|
if (!registered()) {
|
||||||
|
|
|
@ -85,6 +85,9 @@ public:
|
||||||
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
|
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
|
||||||
int accessibleCharacterCount() const override;
|
int accessibleCharacterCount() const override;
|
||||||
|
|
||||||
|
// ListView item Interface
|
||||||
|
int accessibleRowIndex() const override;
|
||||||
|
|
||||||
async::Channel<Property, Val> accessiblePropertyChanged() const override;
|
async::Channel<Property, Val> accessiblePropertyChanged() const override;
|
||||||
async::Channel<State, bool> accessibleStateChanged() const override;
|
async::Channel<State, bool> accessibleStateChanged() const override;
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
CheckBox,
|
CheckBox,
|
||||||
RadioButton,
|
RadioButton,
|
||||||
ComboBox,
|
ComboBox,
|
||||||
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Range,
|
Range,
|
||||||
|
@ -148,6 +149,9 @@ public:
|
||||||
virtual QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const = 0;
|
virtual QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const = 0;
|
||||||
virtual int accessibleCharacterCount() const = 0;
|
virtual int accessibleCharacterCount() const = 0;
|
||||||
|
|
||||||
|
// ListView item Interface
|
||||||
|
virtual int accessibleRowIndex() const = 0;
|
||||||
|
|
||||||
virtual async::Channel<IAccessible::Property, Val> accessiblePropertyChanged() const = 0;
|
virtual async::Channel<IAccessible::Property, Val> accessiblePropertyChanged() const = 0;
|
||||||
|
|
||||||
virtual void setState(State state, bool arg) = 0;
|
virtual void setState(State state, bool arg) = 0;
|
||||||
|
|
|
@ -662,6 +662,11 @@ int AccessibilityController::accessibleCharacterCount() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AccessibilityController::accessibleRowIndex() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
mu::async::Channel<IAccessible::Property, mu::Val> AccessibilityController::accessiblePropertyChanged() const
|
mu::async::Channel<IAccessible::Property, mu::Val> AccessibilityController::accessiblePropertyChanged() const
|
||||||
{
|
{
|
||||||
static async::Channel<IAccessible::Property, Val> ch;
|
static async::Channel<IAccessible::Property, Val> ch;
|
||||||
|
|
|
@ -107,6 +107,9 @@ public:
|
||||||
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
|
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
|
||||||
int accessibleCharacterCount() const override;
|
int accessibleCharacterCount() const override;
|
||||||
|
|
||||||
|
// ListView item Interface
|
||||||
|
int accessibleRowIndex() const override;
|
||||||
|
|
||||||
async::Channel<Property, Val> accessiblePropertyChanged() const override;
|
async::Channel<Property, Val> accessiblePropertyChanged() const override;
|
||||||
async::Channel<State, bool> accessibleStateChanged() const override;
|
async::Channel<State, bool> accessibleStateChanged() const override;
|
||||||
|
|
||||||
|
|
|
@ -153,9 +153,15 @@ QAccessible::State AccessibleItemInterface::state() const
|
||||||
state.focusable = true;
|
state.focusable = true;
|
||||||
state.focused = item->accessibleState(IAccessible::State::Focused);
|
state.focused = item->accessibleState(IAccessible::State::Focused);
|
||||||
} break;
|
} break;
|
||||||
|
case IAccessible::Role::List: {
|
||||||
|
state.active = item->accessibleState(IAccessible::State::Active);
|
||||||
|
} break;
|
||||||
case IAccessible::Role::ListItem: {
|
case IAccessible::Role::ListItem: {
|
||||||
state.focusable = true;
|
state.focusable = true;
|
||||||
state.focused = item->accessibleState(IAccessible::State::Focused);
|
state.focused = item->accessibleState(IAccessible::State::Focused);
|
||||||
|
|
||||||
|
state.selectable = true;
|
||||||
|
state.selected = item->accessibleState(IAccessible::State::Selected);
|
||||||
} break;
|
} break;
|
||||||
case IAccessible::Role::Information: {
|
case IAccessible::Role::Information: {
|
||||||
state.focusable = true;
|
state.focusable = true;
|
||||||
|
@ -213,6 +219,7 @@ QAccessible::Role AccessibleItemInterface::role() const
|
||||||
case IAccessible::Role::CheckBox: return QAccessible::CheckBox;
|
case IAccessible::Role::CheckBox: return QAccessible::CheckBox;
|
||||||
case IAccessible::Role::RadioButton: return QAccessible::RadioButton;
|
case IAccessible::Role::RadioButton: return QAccessible::RadioButton;
|
||||||
case IAccessible::Role::ComboBox: return QAccessible::ComboBox;
|
case IAccessible::Role::ComboBox: return QAccessible::ComboBox;
|
||||||
|
case IAccessible::Role::List: return QAccessible::List;
|
||||||
case IAccessible::Role::ListItem: return QAccessible::ListItem;
|
case IAccessible::Role::ListItem: return QAccessible::ListItem;
|
||||||
case IAccessible::Role::MenuItem: return QAccessible::MenuItem;
|
case IAccessible::Role::MenuItem: return QAccessible::MenuItem;
|
||||||
case IAccessible::Role::Range: return QAccessible::Slider;
|
case IAccessible::Role::Range: return QAccessible::Slider;
|
||||||
|
@ -386,6 +393,51 @@ QString AccessibleItemInterface::attributes(int, int* startOffset, int* endOffse
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AccessibleItemInterface::isSelected() const
|
||||||
|
{
|
||||||
|
return m_object->item()->accessibleState(IAccessible::State::Selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QAccessibleInterface*> AccessibleItemInterface::columnHeaderCells() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED;
|
||||||
|
return QList<QAccessibleInterface*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QAccessibleInterface*> AccessibleItemInterface::rowHeaderCells() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED;
|
||||||
|
return QList<QAccessibleInterface*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AccessibleItemInterface::columnIndex() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AccessibleItemInterface::rowIndex() const
|
||||||
|
{
|
||||||
|
return m_object->item()->accessibleRowIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AccessibleItemInterface::columnExtent() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AccessibleItemInterface::rowExtent() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAccessibleInterface* AccessibleItemInterface::table() const
|
||||||
|
{
|
||||||
|
return parent();
|
||||||
|
}
|
||||||
|
|
||||||
void* AccessibleItemInterface::interface_cast(QAccessible::InterfaceType type)
|
void* AccessibleItemInterface::interface_cast(QAccessible::InterfaceType type)
|
||||||
{
|
{
|
||||||
QAccessible::Role itemRole = role();
|
QAccessible::Role itemRole = role();
|
||||||
|
@ -395,6 +447,17 @@ void* AccessibleItemInterface::interface_cast(QAccessible::InterfaceType type)
|
||||||
return static_cast<QAccessibleTextInterface*>(this);
|
return static_cast<QAccessibleTextInterface*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isListType = type == QAccessible::InterfaceType::TableCellInterface;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
//! NOTE: Without Action and Text interfaces NVDA doesn't work
|
||||||
|
isListType |= type == QAccessible::InterfaceType::ActionInterface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (isListType && itemRole == QAccessible::ListItem) {
|
||||||
|
//! NOTE: Without Action and Text interfaces NVDA doesn't work
|
||||||
|
return static_cast<QAccessibleTableCellInterface*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
//! NOTE Not implemented
|
//! NOTE Not implemented
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
#include "ui/iinteractiveprovider.h"
|
#include "ui/iinteractiveprovider.h"
|
||||||
|
|
||||||
namespace mu::accessibility {
|
namespace mu::accessibility {
|
||||||
class AccessibleItemInterface : public QAccessibleInterface, public QAccessibleValueInterface, public QAccessibleTextInterface
|
class AccessibleItemInterface : public QAccessibleInterface, public QAccessibleValueInterface, public QAccessibleTextInterface,
|
||||||
|
public QAccessibleTableCellInterface
|
||||||
{
|
{
|
||||||
INJECT(ui::IInteractiveProvider, interactiveProvider)
|
INJECT(ui::IInteractiveProvider, interactiveProvider)
|
||||||
|
|
||||||
|
@ -84,6 +85,18 @@ public:
|
||||||
void scrollToSubstring(int startIndex, int endIndex) override;
|
void scrollToSubstring(int startIndex, int endIndex) override;
|
||||||
QString attributes(int /* offset */, int* startOffset, int* endOffset) const override;
|
QString attributes(int /* offset */, int* startOffset, int* endOffset) const override;
|
||||||
|
|
||||||
|
// Table cell(list view item) Interface
|
||||||
|
bool isSelected() const override;
|
||||||
|
|
||||||
|
QList<QAccessibleInterface*> columnHeaderCells() const override;
|
||||||
|
QList<QAccessibleInterface*> rowHeaderCells() const override;
|
||||||
|
int columnIndex() const override;
|
||||||
|
int rowIndex() const override;
|
||||||
|
int columnExtent() const override;
|
||||||
|
int rowExtent() const override;
|
||||||
|
|
||||||
|
QAccessibleInterface* table() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void* interface_cast(QAccessible::InterfaceType t) override;
|
void* interface_cast(QAccessible::InterfaceType t) override;
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ public:
|
||||||
QString accessibleTextAtOffset(int, TextBoundaryType, int*, int*) const override { return QString(); }
|
QString accessibleTextAtOffset(int, TextBoundaryType, int*, int*) const override { return QString(); }
|
||||||
int accessibleCharacterCount() const override { return 0; }
|
int accessibleCharacterCount() const override { return 0; }
|
||||||
|
|
||||||
|
int accessibleRowIndex() const override { return 0; }
|
||||||
|
|
||||||
async::Channel<IAccessible::Property, Val> accessiblePropertyChanged() const override
|
async::Channel<IAccessible::Property, Val> accessiblePropertyChanged() const override
|
||||||
{
|
{
|
||||||
return m_propertyChanged;
|
return m_propertyChanged;
|
||||||
|
|
|
@ -365,6 +365,11 @@ mu::async::Channel<IAccessible::State, bool> AccessibleItem::accessibleStateChan
|
||||||
return m_accessibleStateChanged;
|
return m_accessibleStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AccessibleItem::accessibleRowIndex() const
|
||||||
|
{
|
||||||
|
return m_row;
|
||||||
|
}
|
||||||
|
|
||||||
void AccessibleItem::classBegin()
|
void AccessibleItem::classBegin()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -440,6 +445,11 @@ int AccessibleItem::cursorPosition() const
|
||||||
return m_cursorPosition;
|
return m_cursorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AccessibleItem::row() const
|
||||||
|
{
|
||||||
|
return m_row;
|
||||||
|
}
|
||||||
|
|
||||||
bool AccessibleItem::ignored() const
|
bool AccessibleItem::ignored() const
|
||||||
{
|
{
|
||||||
return m_ignored;
|
return m_ignored;
|
||||||
|
@ -621,6 +631,16 @@ void AccessibleItem::setCursorPosition(int cursorPosition)
|
||||||
m_accessiblePropertyChanged.send(IAccessible::Property::TextCursor, Val());
|
m_accessiblePropertyChanged.send(IAccessible::Property::TextCursor, Val());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AccessibleItem::setRow(int row)
|
||||||
|
{
|
||||||
|
if (m_row == row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_row = row;
|
||||||
|
emit rowChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void AccessibleItem::setIgnored(bool ignored)
|
void AccessibleItem::setIgnored(bool ignored)
|
||||||
{
|
{
|
||||||
if (m_ignored == ignored) {
|
if (m_ignored == ignored) {
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
CheckBox,
|
CheckBox,
|
||||||
RadioButton,
|
RadioButton,
|
||||||
ComboBox,
|
ComboBox,
|
||||||
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Range,
|
Range,
|
||||||
|
@ -84,6 +85,8 @@ class AccessibleItem : public QObject, public QQmlParserStatus, public accessibi
|
||||||
Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged)
|
Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged)
|
||||||
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
|
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
|
||||||
|
|
||||||
Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged)
|
Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged)
|
||||||
Q_PROPERTY(QQuickItem * visualItem READ visualItem WRITE setVisualItem NOTIFY visualItemChanged)
|
Q_PROPERTY(QQuickItem * visualItem READ visualItem WRITE setVisualItem NOTIFY visualItemChanged)
|
||||||
|
|
||||||
|
@ -133,6 +136,9 @@ public:
|
||||||
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
|
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
|
||||||
int accessibleCharacterCount() const override;
|
int accessibleCharacterCount() const override;
|
||||||
|
|
||||||
|
// ListView item Interface
|
||||||
|
int accessibleRowIndex() const override;
|
||||||
|
|
||||||
async::Channel<Property, Val> accessiblePropertyChanged() const override;
|
async::Channel<Property, Val> accessiblePropertyChanged() const override;
|
||||||
|
|
||||||
void setState(State st, bool arg) override;
|
void setState(State st, bool arg) override;
|
||||||
|
@ -159,6 +165,8 @@ public:
|
||||||
int selectionEnd() const;
|
int selectionEnd() const;
|
||||||
int cursorPosition() const;
|
int cursorPosition() const;
|
||||||
|
|
||||||
|
int row() const;
|
||||||
|
|
||||||
bool ignored() const;
|
bool ignored() const;
|
||||||
QQuickItem* visualItem() const;
|
QQuickItem* visualItem() const;
|
||||||
|
|
||||||
|
@ -178,6 +186,7 @@ public slots:
|
||||||
void setSelectionStart(int selectionStart);
|
void setSelectionStart(int selectionStart);
|
||||||
void setSelectionEnd(int selectionEnd);
|
void setSelectionEnd(int selectionEnd);
|
||||||
void setCursorPosition(int cursorPosition);
|
void setCursorPosition(int cursorPosition);
|
||||||
|
void setRow(int row);
|
||||||
void setIgnored(bool ignored);
|
void setIgnored(bool ignored);
|
||||||
void setVisualItem(QQuickItem* item);
|
void setVisualItem(QQuickItem* item);
|
||||||
void setWindow(QWindow* window);
|
void setWindow(QWindow* window);
|
||||||
|
@ -196,6 +205,7 @@ signals:
|
||||||
void selectionStartChanged();
|
void selectionStartChanged();
|
||||||
void selectionEndChanged();
|
void selectionEndChanged();
|
||||||
void cursorPositionChanged();
|
void cursorPositionChanged();
|
||||||
|
void rowChanged();
|
||||||
void ignoredChanged(bool ignored);
|
void ignoredChanged(bool ignored);
|
||||||
void visualItemChanged(QQuickItem* item);
|
void visualItemChanged(QQuickItem* item);
|
||||||
void stateChanged();
|
void stateChanged();
|
||||||
|
@ -224,6 +234,7 @@ private:
|
||||||
int m_selectionStart = 0;
|
int m_selectionStart = 0;
|
||||||
int m_selectionEnd = 0;
|
int m_selectionEnd = 0;
|
||||||
int m_cursorPosition = 0;
|
int m_cursorPosition = 0;
|
||||||
|
int m_row = 0;
|
||||||
bool m_ignored = false;
|
bool m_ignored = false;
|
||||||
QQuickItem* m_visualItem = nullptr;
|
QQuickItem* m_visualItem = nullptr;
|
||||||
QWindow* m_window = nullptr;
|
QWindow* m_window = nullptr;
|
||||||
|
|
|
@ -40,6 +40,37 @@ ListView {
|
||||||
ScrollBar.vertical: root.arrowControlsAvailable ? null : scrollBarComp.createObject(root)
|
ScrollBar.vertical: root.arrowControlsAvailable ? null : scrollBarComp.createObject(root)
|
||||||
ScrollBar.horizontal: root.arrowControlsAvailable ? null : scrollBarComp.createObject(root)
|
ScrollBar.horizontal: root.arrowControlsAvailable ? null : scrollBarComp.createObject(root)
|
||||||
|
|
||||||
|
property alias navigation: navPanel
|
||||||
|
property alias accessible: navPanel.accessible
|
||||||
|
|
||||||
|
NavigationPanel {
|
||||||
|
id: navPanel
|
||||||
|
name: root.objectName !== "" ? root.objectName : "ListView"
|
||||||
|
enabled: root.enabled && root.visible
|
||||||
|
|
||||||
|
accessible.role: MUAccessible.List
|
||||||
|
accessible.name: "List"
|
||||||
|
accessible.visualItem: root
|
||||||
|
accessible.enabled: navPanel.enabled
|
||||||
|
|
||||||
|
onNavigationEvent: function(event) {
|
||||||
|
if (event.type === NavigationEvent.AboutActive) {
|
||||||
|
for (var i = 0; i < root.count; ++i) {
|
||||||
|
var item = root.itemAtIndex(i)
|
||||||
|
if (item.isSelected) {
|
||||||
|
event.setData("controlIndex", [item.navigation.row, item.navigation.column])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstItem = root.itemAtIndex(0)
|
||||||
|
if (Boolean(firstItem)) {
|
||||||
|
event.setData("controlIndex", [firstItem.navigation.row, firstItem.navigation.column])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: scrollBarComp
|
id: scrollBarComp
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,9 @@ Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
accessible.accessibleParent: navPanel.accessible
|
||||||
|
accessible.name: titleLabel.text
|
||||||
|
|
||||||
onModelChanged: {
|
onModelChanged: {
|
||||||
groupsView.currentIndex = Qt.binding(() => (root.currentGroupIndex))
|
groupsView.currentIndex = Qt.binding(() => (root.currentGroupIndex))
|
||||||
}
|
}
|
||||||
|
@ -131,7 +134,9 @@ Item {
|
||||||
navigation.name: modelData
|
navigation.name: modelData
|
||||||
navigation.panel: navPanel
|
navigation.panel: navPanel
|
||||||
navigation.row: 2 + model.index
|
navigation.row: 2 + model.index
|
||||||
|
navigation.accessible.accessibleParent: groupsView.accessible
|
||||||
navigation.accessible.name: itemTitleLabel.text
|
navigation.accessible.name: itemTitleLabel.text
|
||||||
|
navigation.accessible.row: model.index
|
||||||
|
|
||||||
StyledTextLabel {
|
StyledTextLabel {
|
||||||
id: itemTitleLabel
|
id: itemTitleLabel
|
||||||
|
|
Loading…
Reference in a new issue