Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the plugins of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#include "qcocoaaccessibilityelement.h"
40#include "qcocoaaccessibility.h"
41#include "qcocoahelpers.h"
42#include "qcocoawindow.h"
43#include "qcocoascreen.h"
44#include "private/qaccessiblecache_p.h"
45#include <QtAccessibilitySupport/private/qaccessiblebridgeutils_p.h>
46#include <QtGui/qaccessible.h>
47
48#import <AppKit/NSAccessibility.h>
49
50QT_USE_NAMESPACE
51
52#ifndef QT_NO_ACCESSIBILITY
53
54/**
55 * Converts between absolute character offsets and line numbers of a
56 * QAccessibleTextInterface. Works in exactly one of two modes:
57 *
58 * - Pass *line == -1 in order to get a line containing character at the given
59 * *offset
60 * - Pass *offset == -1 in order to get the offset of first character of the
61 * given *line
62 *
63 * You can optionally also pass non-NULL `start` and `end`, which will in both
64 * modes be filled with the offset of the first and last characters of the
65 * relevant line.
66 */
67static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *offset, NSUInteger *start = 0, NSUInteger *end = 0)
68{
69 Q_ASSERT(*line == -1 || *offset == -1);
70 Q_ASSERT(*line != -1 || *offset != -1);
71 Q_ASSERT(*offset <= text->characterCount());
72
73 int curLine = -1;
74 int curStart = 0, curEnd = 0;
75
76 do {
77 curStart = curEnd;
78 text->textAtOffset(curStart, QAccessible::LineBoundary, &curStart, &curEnd);
79 // If the text is empty then we just return
80 if (curStart == -1 || curEnd == -1) {
81 if (start)
82 *start = 0;
83 if (end)
84 *end = 0;
85 return;
86 }
87 ++curLine;
88 {
89 // check for a case where a single word longer than the text edit's width and gets wrapped
90 // in the middle of the word; in this case curEnd will be an offset belonging to the next line
91 // and therefore nextEnd will not be equal to curEnd
92 int nextStart;
93 int nextEnd;
94 text->textAtOffset(curEnd, QAccessible::LineBoundary, &nextStart, &nextEnd);
95 if (nextEnd == curEnd)
96 ++curEnd;
97 }
98 } while ((*line == -1 || curLine < *line) && (*offset == -1 || (curEnd <= *offset)) && curEnd <= text->characterCount());
99
100 curEnd = qMin(curEnd, text->characterCount());
101
102 if (*line == -1)
103 *line = curLine;
104 if (*offset == -1)
105 *offset = curStart;
106
107 Q_ASSERT(curStart >= 0);
108 Q_ASSERT(curEnd >= 0);
109 if (start)
110 *start = curStart;
111 if (end)
112 *end = curEnd;
113}
114
115@implementation QMacAccessibilityElement {
116 QAccessible::Id axid;
117}
118
119- (instancetype)initWithId:(QAccessible::Id)anId
120{
121 Q_ASSERT((int)anId < 0);
122 self = [super init];
123 if (self) {
124 axid = anId;
125 }
126
127 return self;
128}
129
130+ (instancetype)elementWithId:(QAccessible::Id)anId
131{
132 Q_ASSERT(anId);
133 if (!anId)
134 return nil;
135
136 QAccessibleCache *cache = QAccessibleCache::instance();
137
138 QMacAccessibilityElement *element = cache->elementForId(anId);
139 if (!element) {
140 QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
141 Q_ASSERT(iface);
142 if (!iface || !iface->isValid())
143 return nil;
144 element = [[self alloc] initWithId:anId];
145 cache->insertElement(anId, element);
146 }
147 return element;
148}
149
150- (void)invalidate {
151 axid = 0;
152 NSAccessibilityPostNotification(self, NSAccessibilityUIElementDestroyedNotification);
153 [self release];
154}
155
156- (void)dealloc {
157 [super dealloc];
158}
159
160- (BOOL)isEqual:(id)object {
161 if ([object isKindOfClass:[QMacAccessibilityElement class]]) {
162 QMacAccessibilityElement *other = object;
163 return other->axid == axid;
164 } else {
165 return NO;
166 }
167}
168
169- (NSUInteger)hash {
170 return axid;
171}
172
173//
174// accessibility protocol
175//
176
177- (BOOL)isAccessibilityFocused
178{
179 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
180 if (!iface || !iface->isValid()) {
181 return false;
182 }
183 // Just check if the app thinks we're focused.
184 id focusedElement = NSApp.accessibilityApplicationFocusedUIElement;
185 return [focusedElement isEqual:self];
186}
187
188// attributes
189
190+ (id) lineNumberForIndex: (int)index forText:(const QString &)text
191{
192 QStringRef textBefore = QStringRef(&text, 0, index);
193 int newlines = textBefore.count(QLatin1Char('\n'));
194 return @(newlines);
195}
196
197- (BOOL) accessibilityNotifiesWhenDestroyed {
198 return YES;
199}
200
201- (NSString *) accessibilityRole {
202 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
203 if (!iface || !iface->isValid())
204 return NSAccessibilityUnknownRole;
205 return QCocoaAccessible::macRole(iface);
206}
207
208- (NSString *) accessibilitySubRole {
209 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
210 if (!iface || !iface->isValid())
211 return NSAccessibilityUnknownRole;
212 return QCocoaAccessible::macSubrole(iface);
213}
214
215- (NSString *) accessibilityRoleDescription {
216 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
217 if (!iface || !iface->isValid())
218 return NSAccessibilityUnknownRole;
219 return NSAccessibilityRoleDescription(self.accessibilityRole, self.accessibilitySubRole);
220}
221
222- (NSArray *) accessibilityChildren {
223 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
224 if (!iface || !iface->isValid())
225 return nil;
226 return QCocoaAccessible::unignoredChildren(iface);
227}
228
229- (id) accessibilityWindow {
230 // We're in the same window as our parent.
231 return [self.accessibilityParent accessibilityWindow];
232}
233
234- (id) accessibilityTopLevelUIElementAttribute {
235 // We're in the same top level element as our parent.
236 return [self.accessibilityParent accessibilityTopLevelUIElementAttribute];
237}
238
239- (NSString *) accessibilityTitle {
240 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
241 if (!iface || !iface->isValid())
242 return nil;
243 if (iface->role() == QAccessible::StaticText)
244 return nil;
245 return iface->text(QAccessible::Name).toNSString();
246}
247
248- (BOOL) accessibilityEnabledAttribute {
249 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
250 if (!iface || !iface->isValid())
251 return false;
252 return !iface->state().disabled;
253}
254
255- (id)accessibilityParent {
256 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
257 if (!iface || !iface->isValid())
258 return nil;
259
260 // macOS expects that the hierarchy is:
261 // App -> Window -> Children
262 // We don't actually have the window reflected properly in QAccessibility.
263 // Check if the parent is the application and then instead return the native window.
264
265 if (QAccessibleInterface *parent = iface->parent()) {
266 if (parent->role() != QAccessible::Application) {
267 QAccessible::Id parentId = QAccessible::uniqueId(parent);
268 return NSAccessibilityUnignoredAncestor([QMacAccessibilityElement elementWithId: parentId]);
269 }
270 }
271
272 if (QWindow *window = iface->window()) {
273 QPlatformWindow *platformWindow = window->handle();
274 if (platformWindow) {
275 QCocoaWindow *win = static_cast<QCocoaWindow*>(platformWindow);
276 return NSAccessibilityUnignoredAncestor(qnsview_cast(win->view()));
277 }
278 }
279 return nil;
280}
281
282- (NSRect)accessibilityFrame {
283 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
284 if (!iface || !iface->isValid())
285 return NSZeroRect;
286 return QCocoaScreen::mapToNative(iface->rect());
287}
288
289- (NSString*)accessibilityLabel {
290 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
291 if (!iface || !iface->isValid()) {
292 qWarning() << "Called accessibilityLabel on invalid object: " << axid;
293 return nil;
294 }
295 return iface->text(QAccessible::Description).toNSString();
296}
297
298- (void)setAccessibilityLabel:(NSString*)label{
299 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
300 if (!iface || !iface->isValid())
301 return;
302 iface->setText(QAccessible::Description, QString::fromNSString(label));
303}
304
305- (id) accessibilityMinValue:(QAccessibleInterface*)iface {
306 if (QAccessibleValueInterface *val = iface->valueInterface())
307 return @(val->minimumValue().toDouble());
308 return nil;
309}
310
311- (id) accessibilityMaxValue:(QAccessibleInterface*)iface {
312 if (QAccessibleValueInterface *val = iface->valueInterface())
313 return @(val->maximumValue().toDouble());
314 return nil;
315}
316
317- (id) accessibilityValue {
318 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
319 if (!iface || !iface->isValid())
320 return nil;
321
322 // VoiceOver asks for the value attribute for all elements. Return nil
323 // if we don't want the element to have a value attribute.
324 if (!QCocoaAccessible::hasValueAttribute(iface))
325 return nil;
326
327 return QCocoaAccessible::getValueAttribute(iface);
328}
329
330- (NSInteger) accessibilityNumberOfCharacters {
331 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
332 if (!iface || !iface->isValid())
333 return 0;
334 if (QAccessibleTextInterface *text = iface->textInterface())
335 return text->characterCount();
336 return 0;
337}
338
339- (NSString *) accessibilitySelectedText {
340 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
341 if (!iface || !iface->isValid())
342 return nil;
343 if (QAccessibleTextInterface *text = iface->textInterface()) {
344 int start = 0;
345 int end = 0;
346 text->selection(0, &start, &end);
347 return text->text(start, end).toNSString();
348 }
349 return nil;
350}
351
352- (NSRange) accessibilitySelectedTextRange {
353 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
354 if (!iface || !iface->isValid())
355 return NSRange();
356 if (QAccessibleTextInterface *text = iface->textInterface()) {
357 int start = 0;
358 int end = 0;
359 if (text->selectionCount() > 0) {
360 text->selection(0, &start, &end);
361 } else {
362 start = text->cursorPosition();
363 end = start;
364 }
365 return NSMakeRange(quint32(start), quint32(end - start));
366 }
367 return NSMakeRange(0, 0);
368}
369
370- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
371 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
372 if (!iface || !iface->isValid())
373 return 0;
374 if (QAccessibleTextInterface *text = iface->textInterface()) {
375 QString textToPos = text->text(0, index);
376 return textToPos.count('\n');
377 }
378 return 0;
379}
380
381- (NSRange)accessibilityVisibleCharacterRange {
382 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
383 if (!iface || !iface->isValid())
384 return NSRange();
385 // FIXME This is not correct and may impact performance for big texts
386 if (QAccessibleTextInterface *text = iface->textInterface())
387 return NSMakeRange(0, static_cast<uint>(text->characterCount()));
388 return NSMakeRange(0, static_cast<uint>(iface->text(QAccessible::Name).length()));
389}
390
391- (NSInteger) accessibilityInsertionPointLineNumber {
392 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
393 if (!iface || !iface->isValid())
394 return 0;
395 if (QAccessibleTextInterface *text = iface->textInterface()) {
396 int position = text->cursorPosition();
397 return [self accessibilityLineForIndex:position];
398 }
399 return 0;
400}
401
402- (NSArray *)accessibilityParameterizedAttributeNames {
403
404 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
405 if (!iface || !iface->isValid()) {
406 qWarning() << "Called attribute on invalid object: " << axid;
407 return nil;
408 }
409
410 if (iface->textInterface()) {
411 return @[
412 NSAccessibilityStringForRangeParameterizedAttribute,
413 NSAccessibilityLineForIndexParameterizedAttribute,
414 NSAccessibilityRangeForLineParameterizedAttribute,
415 NSAccessibilityRangeForPositionParameterizedAttribute,
416// NSAccessibilityRangeForIndexParameterizedAttribute,
417 NSAccessibilityBoundsForRangeParameterizedAttribute,
418// NSAccessibilityRTFForRangeParameterizedAttribute,
419 NSAccessibilityStyleRangeForIndexParameterizedAttribute,
420 NSAccessibilityAttributedStringForRangeParameterizedAttribute
421 ];
422 }
423
424 return nil;
425}
426
427- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter {
428 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
429 if (!iface || !iface->isValid()) {
430 qWarning() << "Called attribute on invalid object: " << axid;
431 return nil;
432 }
433
434 if (!iface->textInterface())
435 return nil;
436
437 if ([attribute isEqualToString: NSAccessibilityStringForRangeParameterizedAttribute]) {
438 NSRange range = [parameter rangeValue];
439 QString text = iface->textInterface()->text(range.location, range.location + range.length);
440 return text.toNSString();
441 }
442 if ([attribute isEqualToString: NSAccessibilityLineForIndexParameterizedAttribute]) {
443 int index = [parameter intValue];
444 if (index < 0 || index > iface->textInterface()->characterCount())
445 return nil;
446 int line = 0; // true for all single line edits
447 if (iface->state().multiLine) {
448 line = -1;
449 convertLineOffset(iface->textInterface(), &line, &index);
450 }
451 return @(line);
452 }
453 if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) {
454 int line = [parameter intValue];
455 if (line < 0)
456 return nil;
457 int lineOffset = -1;
458 NSUInteger startOffset = 0;
459 NSUInteger endOffset = 0;
460 convertLineOffset(iface->textInterface(), &line, &lineOffset, &startOffset, &endOffset);
461 return [NSValue valueWithRange:NSMakeRange(startOffset, endOffset - startOffset)];
462 }
463 if ([attribute isEqualToString: NSAccessibilityBoundsForRangeParameterizedAttribute]) {
464 NSRange range = [parameter rangeValue];
465 QRect firstRect = iface->textInterface()->characterRect(range.location);
466 QRectF rect;
467 if (range.length > 0) {
468 NSUInteger position = range.location + range.length - 1;
469 if (position > range.location && iface->textInterface()->text(position, position + 1) == QStringLiteral("\n"))
470 --position;
471 QRect lastRect = iface->textInterface()->characterRect(position);
472 rect = firstRect.united(lastRect);
473 } else {
474 rect = firstRect;
475 rect.setWidth(1);
476 }
477 return [NSValue valueWithRect:QCocoaScreen::mapToNative(rect)];
478 }
479 if ([attribute isEqualToString: NSAccessibilityAttributedStringForRangeParameterizedAttribute]) {
480 NSRange range = [parameter rangeValue];
481 QString text = iface->textInterface()->text(range.location, range.location + range.length);
482 return [[NSAttributedString alloc] initWithString:text.toNSString()];
483 } else if ([attribute isEqualToString: NSAccessibilityRangeForPositionParameterizedAttribute]) {
484 QPoint point = QCocoaScreen::mapFromNative([parameter pointValue]).toPoint();
485 int offset = iface->textInterface()->offsetAtPoint(point);
486 return [NSValue valueWithRange:NSMakeRange(static_cast<NSUInteger>(offset), 1)];
487 } else if ([attribute isEqualToString: NSAccessibilityStyleRangeForIndexParameterizedAttribute]) {
488 int start = 0;
489 int end = 0;
490 iface->textInterface()->attributes([parameter intValue], &start, &end);
491 return [NSValue valueWithRange:NSMakeRange(static_cast<NSUInteger>(start), static_cast<NSUInteger>(end - start))];
492 }
493 return nil;
494}
495
496- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
497 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
498 if (!iface || !iface->isValid())
499 return NO;
500
501 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
502 return iface->state().focusable ? YES : NO;
503 } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
504 if (iface->textInterface() && iface->state().editable)
505 return YES;
506 if (iface->valueInterface())
507 return YES;
508 return NO;
509 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
510 return iface->textInterface() ? YES : NO;
511 }
512 return NO;
513}
514
515- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
516 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
517 if (!iface || !iface->isValid())
518 return;
519 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
520 if (QAccessibleActionInterface *action = iface->actionInterface())
521 action->doAction(QAccessibleActionInterface::setFocusAction());
522 } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
523 if (iface->textInterface()) {
524 QString text = QString::fromNSString((NSString *)value);
525 iface->setText(QAccessible::Value, text);
526 } else if (QAccessibleValueInterface *valueIface = iface->valueInterface()) {
527 double val = [value doubleValue];
528 valueIface->setCurrentValue(val);
529 }
530 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
531 if (QAccessibleTextInterface *text = iface->textInterface()) {
532 NSRange range = [value rangeValue];
533 if (range.length > 0)
534 text->setSelection(0, range.location, range.location + range.length);
535 else
536 text->setCursorPosition(range.location);
537 }
538 }
539}
540
541// actions
542
543- (NSArray *)accessibilityActionNames {
544 NSMutableArray *nsActions = [[NSMutableArray new] autorelease];
545 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
546 if (!iface || !iface->isValid())
547 return nsActions;
548
549 const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface);
550 foreach (const QString &qtAction, supportedActionNames) {
551 NSString *nsAction = QCocoaAccessible::getTranslatedAction(qtAction);
552 if (nsAction)
553 [nsActions addObject : nsAction];
554 }
555
556 return nsActions;
557}
558
559- (NSString *)accessibilityActionDescription:(NSString *)action {
560 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
561 if (!iface || !iface->isValid())
562 return nil; // FIXME is that the right return type??
563 QString qtAction = QCocoaAccessible::translateAction(action, iface);
564 QString description;
565 // Return a description from the action interface if this action is not known to the OS.
566 if (qtAction.isEmpty()) {
567 if (QAccessibleActionInterface *actionInterface = iface->actionInterface()) {
568 qtAction = QString::fromNSString((NSString *)action);
569 description = actionInterface->localizedActionDescription(qtAction);
570 }
571 } else {
572 description = qAccessibleLocalizedActionDescription(qtAction);
573 }
574 return description.toNSString();
575}
576
577- (void)accessibilityPerformAction:(NSString *)action {
578 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
579 if (iface && iface->isValid()) {
580 const QString qtAction = QCocoaAccessible::translateAction(action, iface);
581 QAccessibleBridgeUtils::performEffectiveAction(iface, qtAction);
582 }
583}
584
585// misc
586
587- (BOOL)accessibilityIsIgnored {
588 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
589 if (!iface || !iface->isValid())
590 return true;
591 return QCocoaAccessible::shouldBeIgnored(iface);
592}
593
594- (id)accessibilityHitTest:(NSPoint)point {
595 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
596 if (!iface || !iface->isValid()) {
597// qDebug("Hit test: INVALID");
598 return NSAccessibilityUnignoredAncestor(self);
599 }
600
601 QPointF screenPoint = QCocoaScreen::mapFromNative(point);
602 QAccessibleInterface *childInterface = iface->childAt(screenPoint.x(), screenPoint.y());
603 // No child found, meaning we hit this element.
604 if (!childInterface || !childInterface->isValid())
605 return NSAccessibilityUnignoredAncestor(self);
606
607 // find the deepest child at the point
608 QAccessibleInterface *childOfChildInterface = nullptr;
609 do {
610 childOfChildInterface = childInterface->childAt(screenPoint.x(), screenPoint.y());
611 if (childOfChildInterface && childOfChildInterface->isValid())
612 childInterface = childOfChildInterface;
613 } while (childOfChildInterface && childOfChildInterface->isValid());
614
615 QAccessible::Id childId = QAccessible::uniqueId(childInterface);
616 // hit a child, forward to child accessible interface.
617 QMacAccessibilityElement *accessibleElement = [QMacAccessibilityElement elementWithId:childId];
618 if (accessibleElement)
619 return NSAccessibilityUnignoredAncestor(accessibleElement);
620 return NSAccessibilityUnignoredAncestor(self);
621}
622
623- (id)accessibilityFocusedUIElement {
624 QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
625
626 if (!iface || !iface->isValid()) {
627 qWarning("FocusedUIElement for INVALID");
628 return nil;
629 }
630
631 QAccessibleInterface *childInterface = iface->focusChild();
632 if (childInterface && childInterface->isValid()) {
633 QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
634 QMacAccessibilityElement *accessibleElement = [QMacAccessibilityElement elementWithId:childAxid];
635 return NSAccessibilityUnignoredAncestor(accessibleElement);
636 }
637
638 return NSAccessibilityUnignoredAncestor(self);
639}
640
641@end
642
643#endif // QT_NO_ACCESSIBILITY
644

Warning: That file was not part of the compilation database. It may have many parsing errors.