macOS Accessibility: optimize table interface implementation
Store row and column in the QMacAccessibilityElement when creating it so that we can avoid linearly looking for ourselves in the parent's data. Row elements have their m_rowIndex set, Column elements the m_columnIndex, and elements representing a cell have both set. Cells are not managed by the table. Task-number: QTBUG-34337 Pick-to: 6.5 Change-Id: I319fad1f1fda0cfa4c0b95e9e16c25c87df04351 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
11ae55e918
commit
042d753495
@ -117,7 +117,6 @@ static void populateRoleMap()
|
|||||||
roleMap[QAccessible::ColumnHeader] = NSAccessibilityColumnRole;
|
roleMap[QAccessible::ColumnHeader] = NSAccessibilityColumnRole;
|
||||||
roleMap[QAccessible::Row] = NSAccessibilityRowRole;
|
roleMap[QAccessible::Row] = NSAccessibilityRowRole;
|
||||||
roleMap[QAccessible::RowHeader] = NSAccessibilityRowRole;
|
roleMap[QAccessible::RowHeader] = NSAccessibilityRowRole;
|
||||||
roleMap[QAccessible::Cell] = NSAccessibilityTextFieldRole;
|
|
||||||
roleMap[QAccessible::Button] = NSAccessibilityButtonRole;
|
roleMap[QAccessible::Button] = NSAccessibilityButtonRole;
|
||||||
roleMap[QAccessible::EditableText] = NSAccessibilityTextFieldRole;
|
roleMap[QAccessible::EditableText] = NSAccessibilityTextFieldRole;
|
||||||
roleMap[QAccessible::Link] = NSAccessibilityLinkRole;
|
roleMap[QAccessible::Link] = NSAccessibilityLinkRole;
|
||||||
@ -125,7 +124,7 @@ static void populateRoleMap()
|
|||||||
roleMap[QAccessible::Splitter] = NSAccessibilitySplitGroupRole;
|
roleMap[QAccessible::Splitter] = NSAccessibilitySplitGroupRole;
|
||||||
roleMap[QAccessible::List] = NSAccessibilityListRole;
|
roleMap[QAccessible::List] = NSAccessibilityListRole;
|
||||||
roleMap[QAccessible::ListItem] = NSAccessibilityStaticTextRole;
|
roleMap[QAccessible::ListItem] = NSAccessibilityStaticTextRole;
|
||||||
roleMap[QAccessible::Cell] = NSAccessibilityStaticTextRole;
|
roleMap[QAccessible::Cell] = NSAccessibilityCellRole;
|
||||||
roleMap[QAccessible::Client] = NSAccessibilityGroupRole;
|
roleMap[QAccessible::Client] = NSAccessibilityGroupRole;
|
||||||
roleMap[QAccessible::Paragraph] = NSAccessibilityGroupRole;
|
roleMap[QAccessible::Paragraph] = NSAccessibilityGroupRole;
|
||||||
roleMap[QAccessible::Section] = NSAccessibilityGroupRole;
|
roleMap[QAccessible::Section] = NSAccessibilityGroupRole;
|
||||||
|
@ -80,6 +80,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
|
|
||||||
@implementation QMacAccessibilityElement {
|
@implementation QMacAccessibilityElement {
|
||||||
QAccessible::Id axid;
|
QAccessible::Id axid;
|
||||||
|
int m_rowIndex;
|
||||||
|
int m_columnIndex;
|
||||||
|
|
||||||
// used by NSAccessibilityTable
|
// used by NSAccessibilityTable
|
||||||
NSMutableArray<QMacAccessibilityElement *> *rows; // corresponds to accessibilityRows
|
NSMutableArray<QMacAccessibilityElement *> *rows; // corresponds to accessibilityRows
|
||||||
@ -105,12 +107,25 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
axid = anId;
|
axid = anId;
|
||||||
|
m_rowIndex = -1;
|
||||||
|
m_columnIndex = -1;
|
||||||
rows = nil;
|
rows = nil;
|
||||||
columns = nil;
|
columns = nil;
|
||||||
synthesizedRole = role;
|
synthesizedRole = role;
|
||||||
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
|
// table: if this is not created as an element managed by the table, then
|
||||||
if (iface && iface->tableInterface() && !synthesizedRole)
|
// it's either the table itself, or an element created for an already existing
|
||||||
[self updateTableModel];
|
// cell interface (or an element that's not at all related to a table).
|
||||||
|
if (!synthesizedRole) {
|
||||||
|
if (QAccessibleInterface *iface = QAccessible::accessibleInterface(axid)) {
|
||||||
|
if (iface->tableInterface()) {
|
||||||
|
[self updateTableModel];
|
||||||
|
} else if (const auto *cell = iface->tableCellInterface()) {
|
||||||
|
// if we create an element for a table cell, initialize it with row/column
|
||||||
|
m_rowIndex = cell->rowIndex();
|
||||||
|
m_columnIndex = cell->columnIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@ -183,6 +198,10 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
QMacAccessibilityElement *element =
|
QMacAccessibilityElement *element =
|
||||||
[[QMacAccessibilityElement alloc] initWithId:axid role:role];
|
[[QMacAccessibilityElement alloc] initWithId:axid role:role];
|
||||||
if (element) {
|
if (element) {
|
||||||
|
if (role == NSAccessibilityRowRole)
|
||||||
|
element->m_rowIndex = n;
|
||||||
|
else if (role == NSAccessibilityColumnRole)
|
||||||
|
element->m_columnIndex = n;
|
||||||
[array addObject:element];
|
[array addObject:element];
|
||||||
[element release];
|
[element release];
|
||||||
} else {
|
} else {
|
||||||
@ -320,25 +339,26 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
} else if (synthesizedRole == NSAccessibilityRowRole) {
|
} else if (synthesizedRole == NSAccessibilityRowRole) {
|
||||||
// axid matches the parent table axid so that we can easily find the parent table
|
// axid matches the parent table axid so that we can easily find the parent table
|
||||||
// children of row are cell/any items
|
// children of row are cell/any items
|
||||||
QMacAccessibilityElement *tableElement = [QMacAccessibilityElement elementWithId:axid];
|
Q_ASSERT(m_rowIndex >= 0);
|
||||||
Q_ASSERT(tableElement->rows);
|
if (!columns) {
|
||||||
NSUInteger rowIndex = [tableElement->rows indexOfObjectIdenticalTo:self];
|
const int numColumns = table->columnCount();
|
||||||
Q_ASSERT(rowIndex != NSNotFound);
|
columns = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:numColumns];
|
||||||
int numColumns = table->columnCount();
|
for (int i = 0; i < numColumns; ++i) {
|
||||||
NSMutableArray<QMacAccessibilityElement *> *cells =
|
QAccessibleInterface *cell = table->cellAt(m_rowIndex, i);
|
||||||
[NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:numColumns];
|
if (cell && cell->isValid()) {
|
||||||
for (int i = 0; i < numColumns; ++i) {
|
QAccessible::Id cellId = QAccessible::uniqueId(cell);
|
||||||
QAccessibleInterface *cell = table->cellAt(rowIndex, i);
|
QMacAccessibilityElement *element =
|
||||||
if (cell && cell->isValid()) {
|
[QMacAccessibilityElement elementWithId:cellId];
|
||||||
QAccessible::Id cellId = QAccessible::uniqueId(cell);
|
if (element) {
|
||||||
QMacAccessibilityElement *element =
|
element->m_rowIndex = m_rowIndex;
|
||||||
[QMacAccessibilityElement elementWithId:cellId];
|
element->m_columnIndex = i;
|
||||||
if (element) {
|
[columns insertObject:element atIndex:i];
|
||||||
[cells addObject:element];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[columns retain];
|
||||||
}
|
}
|
||||||
return NSAccessibilityUnignoredChildren(cells);
|
return NSAccessibilityUnignoredChildren(columns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QCocoaAccessible::unignoredChildren(iface);
|
return QCocoaAccessible::unignoredChildren(iface);
|
||||||
@ -388,18 +408,19 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
|
|
||||||
if (QAccessibleInterface *parent = iface->parent()) {
|
if (QAccessibleInterface *parent = iface->parent()) {
|
||||||
if (parent->tableInterface()) {
|
if (parent->tableInterface()) {
|
||||||
if (QAccessibleTableCellInterface *cell = iface->tableCellInterface()) {
|
QAccessible::Id parentId = QAccessible::uniqueId(parent);
|
||||||
// parent of cell should be row
|
QMacAccessibilityElement *tableElement =
|
||||||
QAccessible::Id parentId = QAccessible::uniqueId(parent);
|
[QMacAccessibilityElement elementWithId:parentId];
|
||||||
QMacAccessibilityElement *tableElement =
|
|
||||||
[QMacAccessibilityElement elementWithId:parentId];
|
|
||||||
|
|
||||||
const int rowIndex = cell->rowIndex();
|
// parent of cell should be row
|
||||||
if (tableElement->rows && int([tableElement->rows count]) > rowIndex) {
|
int rowIndex = -1;
|
||||||
QMacAccessibilityElement *rowElement = tableElement->rows[rowIndex];
|
if (m_rowIndex >= 0 && m_columnIndex >= 0)
|
||||||
return NSAccessibilityUnignoredAncestor(rowElement);
|
rowIndex = m_rowIndex;
|
||||||
}
|
else if (QAccessibleTableCellInterface *cell = iface->tableCellInterface())
|
||||||
}
|
rowIndex = cell->rowIndex();
|
||||||
|
Q_ASSERT(tableElement->rows && int([tableElement->rows count]) > rowIndex);
|
||||||
|
QMacAccessibilityElement *rowElement = tableElement->rows[rowIndex];
|
||||||
|
return NSAccessibilityUnignoredAncestor(rowElement);
|
||||||
}
|
}
|
||||||
if (parent->role() != QAccessible::Application) {
|
if (parent->role() != QAccessible::Application) {
|
||||||
QAccessible::Id parentId = QAccessible::uniqueId(parent);
|
QAccessible::Id parentId = QAccessible::uniqueId(parent);
|
||||||
@ -436,10 +457,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
int &row = isRow ? cellPos.ry() : cellPos.rx();
|
int &row = isRow ? cellPos.ry() : cellPos.rx();
|
||||||
int &col = isRow ? cellPos.rx() : cellPos.ry();
|
int &col = isRow ? cellPos.rx() : cellPos.ry();
|
||||||
|
|
||||||
QMacAccessibilityElement *tableElement =
|
NSUInteger trackIndex = self.accessibilityIndex;
|
||||||
[QMacAccessibilityElement elementWithId:axid];
|
|
||||||
NSArray *tracks = isRow ? tableElement->rows : tableElement->columns;
|
|
||||||
NSUInteger trackIndex = [tracks indexOfObjectIdenticalTo:self];
|
|
||||||
if (trackIndex != NSNotFound) {
|
if (trackIndex != NSNotFound) {
|
||||||
row = int(trackIndex);
|
row = int(trackIndex);
|
||||||
if (QAccessibleInterface *firstCell = table->cellAt(cellPos.y(), cellPos.x())) {
|
if (QAccessibleInterface *firstCell = table->cellAt(cellPos.y(), cellPos.x())) {
|
||||||
@ -808,13 +826,10 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
|||||||
// axid matches the parent table axid so that we can easily find the parent table
|
// axid matches the parent table axid so that we can easily find the parent table
|
||||||
// children of row are cell/any items
|
// children of row are cell/any items
|
||||||
if (QAccessibleTableInterface *table = iface->tableInterface()) {
|
if (QAccessibleTableInterface *table = iface->tableInterface()) {
|
||||||
QMacAccessibilityElement *tableElement = [QMacAccessibilityElement elementWithId:axid];
|
if (m_rowIndex >= 0)
|
||||||
NSArray *track = synthesizedRole == NSAccessibilityRowRole
|
index = NSInteger(m_rowIndex);
|
||||||
? tableElement->rows : tableElement->columns;
|
else if (m_columnIndex >= 0)
|
||||||
if (track) {
|
index = NSInteger(m_columnIndex);
|
||||||
NSUInteger trackIndex = [track indexOfObjectIdenticalTo:self];
|
|
||||||
index = (NSInteger)trackIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user