diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 27fd32f91f..b319dd072e 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -9,12 +9,17 @@ #include "qcocoawindow.h" #include "qcocoascreen.h" +#include <QtCore/qlogging.h> #include <QtGui/private/qaccessiblecache_p.h> #include <QtGui/private/qaccessiblebridgeutils_p.h> #include <QtGui/qaccessible.h> QT_USE_NAMESPACE +Q_LOGGING_CATEGORY(lcAccessibilityTable, "qt.accessibility.table") + +using namespace Qt::Literals::StringLiterals; + #if QT_CONFIG(accessibility) /** @@ -130,12 +135,37 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (tableInterface) { auto *tableElement = [QMacAccessibilityElement elementWithInterface:table]; Q_ASSERT(tableElement); - Q_ASSERT(tableElement->rows && int(tableElement->rows.count) > m_rowIndex); + if (!tableElement->rows + || int(tableElement->rows.count) <= m_rowIndex + || int(tableElement->rows.count) != tableInterface->rowCount()) { + qCWarning(lcAccessibilityTable) + << "Cell requested for row" << m_rowIndex << "is out of" + << "bounds for table with" << (tableElement->rows ? + tableElement->rows.count : tableInterface->rowCount()) + << "rows! Resizing table model."; + [tableElement updateTableModel]; + } + + Q_ASSERT(tableElement->rows); + Q_ASSERT(int(tableElement->rows.count) > m_rowIndex); + auto *rowElement = tableElement->rows[m_rowIndex]; - if (!rowElement->columns) { + if (!rowElement->columns || int(rowElement->columns.count) != tableInterface->columnCount()) { + if (rowElement->columns) { + qCWarning(lcAccessibilityTable) + << "Table representation column count is out of sync:" + << rowElement->columns.count << "!=" << tableInterface->columnCount(); + } rowElement->columns = [rowElement populateTableRow:rowElement->columns count:tableInterface->columnCount()]; } + + qCDebug(lcAccessibilityTable) << "Creating cell representation for" + << m_rowIndex << m_columnIndex + << "in table with" + << tableElement->rows.count << "rows and" + << rowElement->columns.count << "columns"; + rowElement->columns[m_columnIndex] = self; } } @@ -211,6 +241,10 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSMutableArray *)populateTableArray:(NSMutableArray *)array role:(NSAccessibilityRole)role count:(int)count { if (QAccessibleInterface *iface = self.qtInterface) { + if (array && int(array.count) != count) { + [array release]; + array = nil; + } if (!array) { array = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:count]; [array retain]; @@ -241,6 +275,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSMutableArray *)populateTableRow:(NSMutableArray *)array count:(int)count { Q_ASSERT(synthesizedRole == NSAccessibilityRowRole); + if (array && int(array.count) != count) { + [array release]; + array = nil; + } + if (!array) { array = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:count]; [array retain]; @@ -272,6 +311,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (QAccessibleInterface *iface = self.qtInterface) { if (QAccessibleTableInterface *table = iface->tableInterface()) { Q_ASSERT(!self.isManagedByParent); + qCDebug(lcAccessibilityTable) << "Updating table representation with" + << table->rowCount() << table->columnCount(); rows = [self populateTableArray:rows role:NSAccessibilityRowRole count:table->rowCount()]; columns = [self populateTableArray:columns role:NSAccessibilityColumnRole count:table->columnCount()]; } @@ -434,6 +475,30 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return QCocoaAccessible::unignoredChildren(iface); } +- (NSArray *) accessibilitySelectedChildren { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return nil; + + QAccessibleSelectionInterface *selection = iface->selectionInterface(); + if (!selection) + return nil; + + const QList<QAccessibleInterface *> selectedList = selection->selectedItems(); + const qsizetype numSelected = selectedList.size(); + NSMutableArray<QMacAccessibilityElement *> *selectedChildren = + [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:numSelected]; + for (QAccessibleInterface *selectedChild : selectedList) { + if (selectedChild && selectedChild->isValid()) { + QAccessible::Id id = QAccessible::uniqueId(selectedChild); + QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId:id]; + if (element) + [selectedChildren addObject:element]; + } + } + return NSAccessibilityUnignoredChildren(selectedChildren); +} + - (id) accessibilityWindow { // We're in the same window as our parent. return [self.accessibilityParent accessibilityWindow]; @@ -455,6 +520,12 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return nil; } +- (NSString*) accessibilityIdentifier { + if (QAccessibleInterface *iface = self.qtInterface) + return QAccessibleBridgeUtils::accessibleId(iface).toNSString(); + return nil; +} + - (BOOL) isAccessibilityEnabled { if (QAccessibleInterface *iface = self.qtInterface) return !iface->state().disabled; @@ -466,7 +537,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of // a synthetic cell without interface - shortcut to the row QMacAccessibilityElement *tableElement = [QMacAccessibilityElement elementWithId:axid]; - Q_ASSERT(tableElement && tableElement->rows && int(tableElement->rows.count) > m_rowIndex); + Q_ASSERT(tableElement && tableElement->rows); + Q_ASSERT(int(tableElement->rows.count) > m_rowIndex); QMacAccessibilityElement *rowElement = tableElement->rows[m_rowIndex]; return rowElement; } @@ -496,7 +568,9 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of rowIndex = m_rowIndex; else if (QAccessibleTableCellInterface *cell = iface->tableCellInterface()) rowIndex = cell->rowIndex(); - Q_ASSERT(tableElement->rows && int([tableElement->rows count]) > rowIndex); + Q_ASSERT(tableElement->rows); + if (rowIndex > int([tableElement->rows count]) || rowIndex == -1) + return nil; QMacAccessibilityElement *rowElement = tableElement->rows[rowIndex]; return NSAccessibilityUnignoredAncestor(rowElement); } @@ -714,7 +788,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of QRectF rect; if (range.length > 0) { NSUInteger position = range.location + range.length - 1; - if (position > range.location && iface->textInterface()->text(position, position + 1) == QStringLiteral("\n")) + if (position > range.location && iface->textInterface()->text(position, position + 1) == "\n"_L1) --position; QRect lastRect = iface->textInterface()->characterRect(position); rect = firstRect.united(lastRect); |