Cocoa: Add initial accessibility implementation.
See qcocoaaccessiblity.h for details. For now only the first level of the hierarchy is made accessible. Also add tools/accessibilityinspector which is an utility for inspecting and debugging the Qt accessibility tree. Change-Id: Iff520bec26b3761feb0c2e00471feb379daaa735 Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
parent
d884f24fe1
commit
946805f07f
@ -7,6 +7,7 @@ OBJECTIVE_SOURCES += main.mm \
|
||||
qcocoabackingstore.mm \
|
||||
qcocoawindow.mm \
|
||||
qnsview.mm \
|
||||
qnsviewaccessibility.mm \
|
||||
qcocoaautoreleasepool.mm \
|
||||
qnswindowdelegate.mm \
|
||||
qcocoaglcontext.mm \
|
||||
@ -19,6 +20,8 @@ OBJECTIVE_SOURCES += main.mm \
|
||||
qmenu_mac.mm \
|
||||
qcocoahelpers.mm \
|
||||
qmultitouch_mac.mm \
|
||||
qcocoaaccessibilityelement.mm \
|
||||
qcocoaaccessibility.mm \
|
||||
|
||||
HEADERS += qcocoaintegration.h \
|
||||
qcocoabackingstore.h \
|
||||
@ -36,6 +39,8 @@ HEADERS += qcocoaintegration.h \
|
||||
qmenu_mac.h \
|
||||
qcocoahelpers.h \
|
||||
qmultitouch_mac_p.h \
|
||||
qcocoaaccessibilityelement.h \
|
||||
qcocoaaccessibility.h \
|
||||
|
||||
RESOURCES += qcocoaresources.qrc
|
||||
|
||||
@ -47,3 +52,7 @@ QT += core-private gui-private widgets-private platformsupport-private
|
||||
CONFIG += qpa/basicunixfontdatabase
|
||||
target.path += $$[QT_INSTALL_PLUGINS]/platforms
|
||||
INSTALLS += target
|
||||
|
||||
# Acccessibility debug support
|
||||
# DEFINES += QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
|
||||
# include ($$PWD/../../../../tools/accessibilityinspector/accessibilityinspector.pri)
|
||||
|
68
src/plugins/platforms/cocoa/qcocoaaccessibility.h
Normal file
68
src/plugins/platforms/cocoa/qcocoaaccessibility.h
Normal file
@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef QCOCOAACCESIBILITY_H
|
||||
#define QCOCOAACCESIBILITY_H
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
/*
|
||||
Qt Cocoa Accessibility Overview
|
||||
|
||||
Cocoa accessibility is implemented in the following files:
|
||||
|
||||
- qnsviewaccessibility : Root accessibility implementation for QNSView
|
||||
- qcocoaaccessibilityelement : Cocoa accessibility protocol wrapper for QAccessibleInterface
|
||||
- qcocoaaccessibility (this file) : Conversion and helper functions.
|
||||
|
||||
The accessibility implementation wraps QAccessibleInterfaces in QCocoaAccessibleElements, which
|
||||
implements the cocoa accessibility protocol. The root QAccessibleInterface (the one returned
|
||||
by QWindow::accessibleRoot), is anchored to the QNSView in qnsviewaccessibility.mm.
|
||||
|
||||
Cocoa explores the accessibility tree by walking the tree using the parent/child
|
||||
relationships or hit testing. When this happens we create QCocoaAccessibleElements on
|
||||
demand.
|
||||
*/
|
||||
|
||||
NSString *macRole(QAccessible::Role);
|
||||
|
||||
#endif
|
113
src/plugins/platforms/cocoa/qcocoaaccessibility.mm
Normal file
113
src/plugins/platforms/cocoa/qcocoaaccessibility.mm
Normal file
@ -0,0 +1,113 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qcocoaaccessibility.h"
|
||||
|
||||
typedef QMap<QAccessible::Role, NSString *> QMacAccessibiltyRoleMap;
|
||||
Q_GLOBAL_STATIC(QMacAccessibiltyRoleMap, qMacAccessibiltyRoleMap);
|
||||
|
||||
static void populateRoleMap()
|
||||
{
|
||||
QMacAccessibiltyRoleMap &roleMap = *qMacAccessibiltyRoleMap();
|
||||
roleMap[QAccessible::MenuItem] = NSAccessibilityMenuItemRole;
|
||||
roleMap[QAccessible::MenuBar] = NSAccessibilityMenuBarRole;
|
||||
roleMap[QAccessible::ScrollBar] = NSAccessibilityScrollBarRole;
|
||||
roleMap[QAccessible::Grip] = NSAccessibilityGrowAreaRole;
|
||||
roleMap[QAccessible::Window] = NSAccessibilityWindowRole;
|
||||
roleMap[QAccessible::Dialog] = NSAccessibilityWindowRole;
|
||||
roleMap[QAccessible::AlertMessage] = NSAccessibilityWindowRole;
|
||||
roleMap[QAccessible::ToolTip] = NSAccessibilityWindowRole;
|
||||
roleMap[QAccessible::HelpBalloon] = NSAccessibilityWindowRole;
|
||||
roleMap[QAccessible::PopupMenu] = NSAccessibilityMenuRole;
|
||||
roleMap[QAccessible::Application] = NSAccessibilityApplicationRole;
|
||||
roleMap[QAccessible::Pane] = NSAccessibilityGroupRole;
|
||||
roleMap[QAccessible::Grouping] = NSAccessibilityGroupRole;
|
||||
roleMap[QAccessible::Separator] = NSAccessibilitySplitterRole;
|
||||
roleMap[QAccessible::ToolBar] = NSAccessibilityToolbarRole;
|
||||
roleMap[QAccessible::PageTab] = NSAccessibilityRadioButtonRole;
|
||||
roleMap[QAccessible::ButtonMenu] = NSAccessibilityMenuButtonRole;
|
||||
roleMap[QAccessible::ButtonDropDown] = NSAccessibilityPopUpButtonRole;
|
||||
roleMap[QAccessible::SpinBox] = NSAccessibilityIncrementorRole;
|
||||
roleMap[QAccessible::Slider] = NSAccessibilitySliderRole;
|
||||
roleMap[QAccessible::ProgressBar] = NSAccessibilityProgressIndicatorRole;
|
||||
roleMap[QAccessible::ComboBox] = NSAccessibilityPopUpButtonRole;
|
||||
roleMap[QAccessible::RadioButton] = NSAccessibilityRadioButtonRole;
|
||||
roleMap[QAccessible::CheckBox] = NSAccessibilityCheckBoxRole;
|
||||
roleMap[QAccessible::StaticText] = NSAccessibilityStaticTextRole;
|
||||
roleMap[QAccessible::Table] = NSAccessibilityTableRole;
|
||||
roleMap[QAccessible::StatusBar] = NSAccessibilityStaticTextRole;
|
||||
roleMap[QAccessible::Column] = NSAccessibilityColumnRole;
|
||||
roleMap[QAccessible::ColumnHeader] = NSAccessibilityColumnRole;
|
||||
roleMap[QAccessible::Row] = NSAccessibilityRowRole;
|
||||
roleMap[QAccessible::RowHeader] = NSAccessibilityRowRole;
|
||||
roleMap[QAccessible::Cell] = NSAccessibilityTextFieldRole;
|
||||
roleMap[QAccessible::PushButton] = NSAccessibilityButtonRole;
|
||||
roleMap[QAccessible::EditableText] = NSAccessibilityTextFieldRole;
|
||||
roleMap[QAccessible::Link] = NSAccessibilityTextFieldRole;
|
||||
roleMap[QAccessible::Indicator] = NSAccessibilityValueIndicatorRole;
|
||||
roleMap[QAccessible::Splitter] = NSAccessibilitySplitGroupRole;
|
||||
roleMap[QAccessible::List] = NSAccessibilityListRole;
|
||||
roleMap[QAccessible::ListItem] = NSAccessibilityStaticTextRole;
|
||||
roleMap[QAccessible::Cell] = NSAccessibilityStaticTextRole;
|
||||
roleMap[QAccessible::Client] = NSAccessibilityGroupRole;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a Mac accessibility role for the given interface, or
|
||||
NSAccessibilityUnknownRole if no role mapping is found.
|
||||
*/
|
||||
NSString *macRole(QAccessible::Role qtRole)
|
||||
{
|
||||
QMacAccessibiltyRoleMap &roleMap = *qMacAccessibiltyRoleMap();
|
||||
|
||||
if (roleMap.isEmpty())
|
||||
populateRoleMap();
|
||||
|
||||
// MAC_ACCESSIBILTY_DEBUG() << "role for" << interface.object() << "interface role" << hex << qtRole;
|
||||
|
||||
if (roleMap.contains(qtRole)) {
|
||||
// MAC_ACCESSIBILTY_DEBUG() << "return" << roleMap[qtRole];
|
||||
return roleMap[qtRole];
|
||||
}
|
||||
|
||||
// MAC_ACCESSIBILTY_DEBUG() << "return NSAccessibilityUnknownRole";
|
||||
return NSAccessibilityUnknownRole;
|
||||
}
|
||||
|
65
src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
Normal file
65
src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef QCOCOAACCESIBILITYELEMENT_H
|
||||
#define QCOCOAACCESIBILITYELEMENT_H
|
||||
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <AppKit/NSAccessibility.h>
|
||||
|
||||
@class QCocoaAccessibleElement;
|
||||
|
||||
@interface QCocoaAccessibleElement : NSObject {
|
||||
NSUInteger index;
|
||||
NSString *role;
|
||||
NSObject * parent;
|
||||
void *accessibleInterface;
|
||||
|
||||
}
|
||||
|
||||
- (id)initWithIndex:(int)aIndex parent:(id)aParent accessibleInterface:(void *)anQAccessibleInterface;
|
||||
+ (QCocoaAccessibleElement *)elementWithIndex:(int)aIndex parent:(id)aParent accessibleInterface:(void *)anQAccessibleInterface;
|
||||
- (NSUInteger)index;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
197
src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
Normal file
197
src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
Normal file
@ -0,0 +1,197 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qcocoaaccessibilityelement.h"
|
||||
#include "qcocoaaccessibility.h"
|
||||
#include "qcocoahelpers.h"
|
||||
|
||||
#include <QAccessible>
|
||||
#include "QAccessibleActionInterface"
|
||||
|
||||
#import <AppKit/NSAccessibility.h>
|
||||
|
||||
static QAccessibleInterface *acast(void *ptr)
|
||||
{
|
||||
return reinterpret_cast<QAccessibleInterface *>(ptr);
|
||||
}
|
||||
|
||||
@implementation QCocoaAccessibleElement
|
||||
|
||||
- (id)initWithIndex:(int)aIndex parent:(id)aParent accessibleInterface:(void *)anQAccessibleInterface
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
index = aIndex;
|
||||
accessibleInterface = anQAccessibleInterface;
|
||||
role = macRole(acast(accessibleInterface)->role());
|
||||
parent = aParent;
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (QCocoaAccessibleElement *)elementWithIndex:(int)aIndex parent:(id)aParent accessibleInterface:(void *)anQAccessibleInterface
|
||||
{
|
||||
return [[[self alloc] initWithIndex:aIndex parent:aParent accessibleInterface:anQAccessibleInterface] autorelease];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([object isKindOfClass:[QCocoaAccessibleElement class]]) {
|
||||
QCocoaAccessibleElement *other = object;
|
||||
return (index == other->index) && [role isEqualToString:other->role] && [parent isEqual:other->parent];
|
||||
} else
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return [parent hash] + index;
|
||||
}
|
||||
|
||||
- (NSUInteger)index {
|
||||
return index;
|
||||
}
|
||||
|
||||
//
|
||||
// accessibility protocol
|
||||
//
|
||||
|
||||
// attributes
|
||||
|
||||
- (NSArray *)accessibilityAttributeNames {
|
||||
static NSArray *attributes = nil;
|
||||
if (attributes == nil) {
|
||||
attributes = [[NSArray alloc] initWithObjects:
|
||||
NSAccessibilityRoleAttribute,
|
||||
NSAccessibilityRoleDescriptionAttribute,
|
||||
NSAccessibilityFocusedAttribute,
|
||||
NSAccessibilityParentAttribute,
|
||||
NSAccessibilityWindowAttribute,
|
||||
NSAccessibilityTopLevelUIElementAttribute,
|
||||
NSAccessibilityPositionAttribute,
|
||||
NSAccessibilitySizeAttribute,
|
||||
NSAccessibilityDescriptionAttribute,
|
||||
nil];
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute {
|
||||
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
|
||||
return role;
|
||||
} else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
|
||||
return NSAccessibilityRoleDescription(role, nil);
|
||||
} else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
|
||||
// Just check if the app thinks we're focused.
|
||||
id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute];
|
||||
return [NSNumber numberWithBool:[focusedElement isEqual:self]];
|
||||
} else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
|
||||
return NSAccessibilityUnignoredAncestor(parent);
|
||||
} else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
|
||||
// We're in the same window as our parent.
|
||||
return [parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
|
||||
} else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) {
|
||||
// We're in the same top level element as our parent.
|
||||
return [parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
|
||||
} else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
|
||||
QPoint qtPosition = acast(accessibleInterface)->rect().topLeft();
|
||||
QSize qtSize = acast(accessibleInterface)->rect().size();
|
||||
return [NSValue valueWithPoint: NSMakePoint(qtPosition.x(), qt_mac_flipYCoordinate(qtPosition.y() + qtSize.height()))];
|
||||
} else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
|
||||
QSize qtSize = acast(accessibleInterface)->rect().size();
|
||||
return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())];
|
||||
} else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
|
||||
return qt_mac_QStringToNSString(acast(accessibleInterface)->text(QAccessible::Name));
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
|
||||
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
|
||||
return NO; // YES to handle keyboard input
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
|
||||
Q_UNUSED(value);
|
||||
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// actions
|
||||
|
||||
- (NSArray *)accessibilityActionNames {
|
||||
return [NSArray arrayWithObject:NSAccessibilityPressAction];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityActionDescription:(NSString *)action {
|
||||
return NSAccessibilityActionDescription(action);
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString *)action {
|
||||
Q_UNUSED(action);
|
||||
if (acast(accessibleInterface)->actionInterface())
|
||||
acast(accessibleInterface)->actionInterface()->doAction(0);
|
||||
}
|
||||
|
||||
// misc
|
||||
|
||||
- (BOOL)accessibilityIsIgnored {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point {
|
||||
Q_UNUSED(point);
|
||||
return NSAccessibilityUnignoredAncestor(self);
|
||||
}
|
||||
|
||||
- (id)accessibilityFocusedUIElement {
|
||||
return NSAccessibilityUnignoredAncestor(self);
|
||||
}
|
||||
|
||||
@end
|
@ -45,11 +45,13 @@
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QAccessible>
|
||||
|
||||
@interface QNSView : NSView {
|
||||
CGImageRef m_cgImage;
|
||||
QWindow *m_window;
|
||||
Qt::MouseButtons m_buttons;
|
||||
QAccessibleInterface *m_accessibleRoot;
|
||||
}
|
||||
|
||||
- (id)init;
|
||||
|
@ -48,6 +48,10 @@
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
|
||||
#include <accessibilityinspector.h>
|
||||
#endif
|
||||
|
||||
@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
|
||||
- (CGFloat)deviceDeltaX;
|
||||
- (CGFloat)deviceDeltaY;
|
||||
@ -58,7 +62,7 @@
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
|
||||
if (self) {
|
||||
m_cgImage = 0;
|
||||
m_window = 0;
|
||||
@ -67,11 +71,31 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithQWindow:(QWindow *)widget {
|
||||
- (id)initWithQWindow:(QWindow *)window {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
m_window = widget;
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
m_window = window;
|
||||
m_accessibleRoot = 0;
|
||||
|
||||
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
|
||||
// prevent rift in space-time continuum, disable
|
||||
// accessibility for the accessibility inspector's windows.
|
||||
static bool skipAccessibilityForInspectorWindows = false;
|
||||
if (!skipAccessibilityForInspectorWindows) {
|
||||
|
||||
m_accessibleRoot = window->accessibleRoot();
|
||||
|
||||
AccessibilityInspector *inspector = new AccessibilityInspector(window);
|
||||
skipAccessibilityForInspectorWindows = true;
|
||||
inspector->inspectWindow(window);
|
||||
skipAccessibilityForInspectorWindows = false;
|
||||
}
|
||||
#else
|
||||
m_accessibleRoot = window->accessibleRoot();
|
||||
#endif
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
117
src/plugins/platforms/cocoa/qnsviewaccessibility.mm
Normal file
117
src/plugins/platforms/cocoa/qnsviewaccessibility.mm
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#include "qnsview.h"
|
||||
#include "qcocoahelpers.h"
|
||||
#include "qcocoaaccessibility.h"
|
||||
#include "qcocoaaccessibilityelement.h"
|
||||
|
||||
#include "QAccessibleActionInterface"
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#import <AppKit/NSAccessibility.h>
|
||||
|
||||
@implementation QNSView (QNSViewAccessibility)
|
||||
|
||||
- (BOOL)accessibilityIsIgnored {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute {
|
||||
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
|
||||
if (m_accessibleRoot)
|
||||
return macRole(m_accessibleRoot->role());
|
||||
return NSAccessibilityUnknownRole;
|
||||
} else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
|
||||
return NSAccessibilityRoleDescriptionForUIElement(self);
|
||||
} else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
if (!m_accessibleRoot)
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
// Create QCocoaAccessibleElements for each child if the
|
||||
// root accessible interface.
|
||||
int numKids = m_accessibleRoot->childCount();
|
||||
NSMutableArray *kids = [NSMutableArray arrayWithCapacity:numKids];
|
||||
for (int i = 0; i < numKids; ++i) {
|
||||
[kids addObject:[QCocoaAccessibleElement elementWithIndex:i parent:self accessibleInterface:(void*)m_accessibleRoot->child(i)]];
|
||||
}
|
||||
|
||||
return NSAccessibilityUnignoredChildren(kids);
|
||||
} else {
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point {
|
||||
NSPoint windowPoint = [[self window] convertScreenToBase:point];
|
||||
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
|
||||
|
||||
int index = -1;
|
||||
if (m_accessibleRoot) {
|
||||
index = m_accessibleRoot->childAt(point.x, qt_mac_flipYCoordinate(point.y));
|
||||
|
||||
// qDebug() << "root rect" << m_accessibleRoot->rect();
|
||||
// qDebug() << "hit screen" << point.x << qt_mac_flipYCoordinate(point.y) << index;
|
||||
// if (index > 0) {
|
||||
// qDebug() << "child name" << m_accessibleRoot->child(index - 1)->text(QAccessible::Name);
|
||||
// qDebug() << "child rect" << m_accessibleRoot->child(index - 1)->rect();
|
||||
// }
|
||||
}
|
||||
|
||||
// hit outside
|
||||
if (index == -1) {
|
||||
return [super accessibilityHitTest:point];
|
||||
}
|
||||
|
||||
// hit the NSView / top-level window
|
||||
if (index == 0) {
|
||||
QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:index parent:self accessibleInterface:(void*)m_accessibleRoot];
|
||||
return [accessibleElement accessibilityHitTest:point];
|
||||
}
|
||||
|
||||
// hit a child, forward to child accessible interface.
|
||||
QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:index - 1 parent:self accessibleInterface:(void*)m_accessibleRoot->child(index -1)];
|
||||
return [accessibleElement accessibilityHitTest:point];
|
||||
}
|
||||
|
||||
@end
|
189
tools/accessibilityinspector/accessibilityinspector.cpp
Normal file
189
tools/accessibilityinspector/accessibilityinspector.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "accessibilityinspector.h"
|
||||
|
||||
#include "screenreader.h"
|
||||
#include "optionswidget.h"
|
||||
#include "accessibilityscenemanager.h"
|
||||
|
||||
#include <QtDeclarative/QtDeclarative>
|
||||
|
||||
void MouseInterceptingGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
emit mousePressed(event->scenePos().toPoint());
|
||||
QGraphicsScene::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void MouseInterceptingGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
emit mouseDobleClicked();
|
||||
QGraphicsScene::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
AccessibilitySceneManager *sceneManager = 0;
|
||||
QAccessible::UpdateHandler previousUpdateHandler = 0;
|
||||
bool updateHandlerRecursion = false;
|
||||
void accessibilityUpdateHandler(QObject *object, int who, QAccessible::Event reason)
|
||||
{
|
||||
if (updateHandlerRecursion)
|
||||
return;
|
||||
|
||||
if (!qobject_cast<QSGItem *>(object))
|
||||
return;
|
||||
|
||||
updateHandlerRecursion = true;
|
||||
|
||||
if (sceneManager) {
|
||||
sceneManager->handleUpdate(object, reason);
|
||||
|
||||
//qDebug() << "update";
|
||||
}
|
||||
|
||||
if (previousUpdateHandler) // call prev just to be sure.
|
||||
previousUpdateHandler(object, who, reason);
|
||||
|
||||
updateHandlerRecursion = false;
|
||||
}
|
||||
|
||||
AccessibilityInspector::AccessibilityInspector(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
AccessibilityInspector::~AccessibilityInspector()
|
||||
{
|
||||
delete optionsWidget;
|
||||
delete accessibilityScene;
|
||||
delete accessibilityView;
|
||||
delete accessibilityTreeScene;
|
||||
delete accessibilityTreeView;
|
||||
delete screenReader;
|
||||
}
|
||||
|
||||
void AccessibilityInspector::inspectWindow(QWindow *window)
|
||||
{
|
||||
qDebug() << "AccessibilityInspector::inspectWindow()" << window;
|
||||
|
||||
optionsWidget = new OptionsWidget();
|
||||
|
||||
accessibilityScene = new MouseInterceptingGraphicsScene();
|
||||
|
||||
accessibilityView = new QGraphicsView();
|
||||
accessibilityView->setScene(accessibilityScene);
|
||||
accessibilityView->resize(1024, 768);
|
||||
accessibilityView->scale(1.3, 1.3);
|
||||
|
||||
accessibilityTreeScene = new QGraphicsScene();
|
||||
|
||||
accessibilityTreeView = new QGraphicsView();
|
||||
accessibilityTreeView->setScene(accessibilityTreeScene);
|
||||
accessibilityTreeView->resize(1024, 768);
|
||||
|
||||
sceneManager = new AccessibilitySceneManager();
|
||||
QObject::connect(optionsWidget, SIGNAL(optionsChanged()), sceneManager, SLOT(updateAccessibilitySceneItemFlags()));
|
||||
QObject::connect(optionsWidget, SIGNAL(refreshClicked()), sceneManager, SLOT(populateAccessibilityScene()));
|
||||
QObject::connect(optionsWidget, SIGNAL(refreshClicked()), sceneManager, SLOT(populateAccessibilityTreeScene()));
|
||||
QObject::connect(optionsWidget, SIGNAL(scaleChanged(int)), sceneManager, SLOT(changeScale(int)));
|
||||
|
||||
sceneManager->setOptionsWidget(optionsWidget);
|
||||
sceneManager->setRootWindow(window);
|
||||
sceneManager->setScene(accessibilityScene);
|
||||
sceneManager->setView(accessibilityView);
|
||||
sceneManager->setTreeScene(accessibilityTreeScene);
|
||||
sceneManager->setTreeView(accessibilityTreeView);
|
||||
|
||||
screenReader = new ScreenReader;
|
||||
QObject::connect(accessibilityScene, SIGNAL(mousePressed(QPoint)), screenReader, SLOT(touchPoint(QPoint)));
|
||||
QObject::connect(accessibilityScene, SIGNAL(mouseDobleClicked()), screenReader, SLOT(activate()));
|
||||
QObject::connect(screenReader, SIGNAL(selected(QObject*)), sceneManager, SLOT(setSelected(QObject*)));
|
||||
screenReader->setRootObject(window);
|
||||
screenReader->setOptionsWidget(optionsWidget);
|
||||
|
||||
previousUpdateHandler = QAccessible::installUpdateHandler(accessibilityUpdateHandler);
|
||||
|
||||
QTimer::singleShot(100, sceneManager, SLOT(populateAccessibilityScene()));
|
||||
QTimer::singleShot(100, sceneManager, SLOT(populateAccessibilityTreeScene()));
|
||||
|
||||
QSettings settings;
|
||||
accessibilityView->restoreGeometry(settings.value("accessiblityGeometry").toByteArray());
|
||||
accessibilityView->setObjectName(QLatin1String("accessibilityInspectorView"));
|
||||
accessibilityView->show();
|
||||
|
||||
|
||||
accessibilityTreeView->restoreGeometry(settings.value("treeGeometry").toByteArray());
|
||||
accessibilityTreeView->setObjectName(QLatin1String("accessibilityInspectorTreeView"));
|
||||
accessibilityTreeView->show();
|
||||
optionsWidget->restoreGeometry(settings.value("optionsGeometry").toByteArray());
|
||||
optionsWidget->setObjectName(QLatin1String("accessibilityInspectorOptions"));
|
||||
optionsWidget->show();
|
||||
}
|
||||
|
||||
void AccessibilityInspector::saveWindowGeometry()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("accessiblityGeometry", accessibilityView->saveGeometry());
|
||||
settings.setValue("treeGeometry", accessibilityTreeView->saveGeometry());
|
||||
settings.setValue("optionsGeometry", optionsWidget->saveGeometry());
|
||||
}
|
||||
|
||||
QString translateRole(QAccessible::Role role)
|
||||
{
|
||||
if (role == 0x2B)
|
||||
return "PushButton";
|
||||
if (role == 0x2C)
|
||||
return "CheckBox";
|
||||
if (role == 0x2D)
|
||||
return "RadioButton";
|
||||
if (role == 0xA)
|
||||
return "Client";
|
||||
if (role == 0x29)
|
||||
return "Static Text";
|
||||
if (role == 0x33)
|
||||
return "Slider";
|
||||
if (role == 0x33)
|
||||
return "Slider";
|
||||
if (role == 0x10)
|
||||
return "Pane";
|
||||
|
||||
return QString::number(role, 16);
|
||||
}
|
||||
|
89
tools/accessibilityinspector/accessibilityinspector.h
Normal file
89
tools/accessibilityinspector/accessibilityinspector.h
Normal file
@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ACCESSIBILITYINSPECTOR_H
|
||||
#define ACCESSIBILITYINSPECTOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qgraphicsscene.h>
|
||||
#include <QAccessible>
|
||||
|
||||
QString translateRole(QAccessible::Role role);
|
||||
|
||||
class OptionsWidget;
|
||||
class MouseInterceptingGraphicsScene;
|
||||
class QGraphicsView;
|
||||
class QGraphicsScene;
|
||||
class AccessibilitySceneManager;
|
||||
class ScreenReader;
|
||||
class AccessibilityInspector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AccessibilityInspector(QObject *parent = 0);
|
||||
~AccessibilityInspector();
|
||||
void inspectWindow(QWindow *window);
|
||||
void saveWindowGeometry();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
OptionsWidget *optionsWidget;
|
||||
MouseInterceptingGraphicsScene *accessibilityScene;
|
||||
QGraphicsView *accessibilityView;
|
||||
QGraphicsScene *accessibilityTreeScene;
|
||||
QGraphicsView *accessibilityTreeView;
|
||||
ScreenReader *screenReader;
|
||||
};
|
||||
|
||||
class MouseInterceptingGraphicsScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
|
||||
signals:
|
||||
void mousePressed(const QPoint point);
|
||||
void mouseDobleClicked();
|
||||
};
|
||||
|
||||
#endif // ACCESSIBILITYINSPECTOR_H
|
25
tools/accessibilityinspector/accessibilityinspector.pri
Normal file
25
tools/accessibilityinspector/accessibilityinspector.pri
Normal file
@ -0,0 +1,25 @@
|
||||
QT += declarative
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
# DEFINES += ACCESSIBILITYINSPECTOR_NO_UITOOLS
|
||||
# CONFIG += uitools
|
||||
|
||||
mac {
|
||||
# for text-to-speach
|
||||
LIBS += -framework AppKit
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/screenreader.h \
|
||||
$$PWD/optionswidget.h \
|
||||
$$PWD/accessibilityscenemanager.h \
|
||||
$$PWD/accessibilityinspector.h
|
||||
SOURCES += \
|
||||
$$PWD/optionswidget.cpp \
|
||||
$$PWD/accessibilityscenemanager.cpp \
|
||||
$$PWD/screenreader.cpp \
|
||||
$$PWD/accessibilityinspector.cpp
|
||||
|
||||
OBJECTIVE_SOURCES += $$PWD/screenreader_mac.mm
|
||||
|
||||
|
5
tools/accessibilityinspector/accessibilityinspector.pro
Normal file
5
tools/accessibilityinspector/accessibilityinspector.pro
Normal file
@ -0,0 +1,5 @@
|
||||
include (accessibilityinspector.pri)
|
||||
|
||||
SOURCES += main.cpp \
|
||||
|
||||
CONFIG += console
|
487
tools/accessibilityinspector/accessibilityscenemanager.cpp
Normal file
487
tools/accessibilityinspector/accessibilityscenemanager.cpp
Normal file
@ -0,0 +1,487 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "accessibilityscenemanager.h"
|
||||
|
||||
AccessibilitySceneManager::AccessibilitySceneManager()
|
||||
{
|
||||
m_window = 0;
|
||||
m_view = 0;
|
||||
m_scene = 0;
|
||||
m_rootItem = 0;
|
||||
m_optionsWidget = 0;
|
||||
m_selectedObject = 0;
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::populateAccessibilityScene()
|
||||
{
|
||||
m_scene->clear();
|
||||
m_graphicsItems.clear();
|
||||
|
||||
QAccessibleInterface * rootInterface = m_window->accessibleRoot();
|
||||
if (!rootInterface)
|
||||
return;
|
||||
|
||||
populateAccessibilityScene(rootInterface, 0, m_scene);
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::updateAccessibilitySceneItemFlags()
|
||||
{
|
||||
qDebug() << "update";
|
||||
foreach (QObject *object, m_graphicsItems.keys()) {
|
||||
if (!object)
|
||||
continue;
|
||||
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
|
||||
if (!interface)
|
||||
continue;
|
||||
updateItemFlags(m_graphicsItems.value(object), interface);
|
||||
delete interface;
|
||||
}
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::populateAccessibilityTreeScene()
|
||||
{
|
||||
m_treeScene->clear();
|
||||
QAccessibleInterface * rootInterface = m_window->accessibleRoot();
|
||||
if (!rootInterface)
|
||||
return;
|
||||
|
||||
populateAccessibilityTreeScene(rootInterface, 0);
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::handleUpdate(QObject *object, QAccessible::Event reason)
|
||||
{
|
||||
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
QString name = interface->text(QAccessible::Name, 0);
|
||||
|
||||
if (reason == QAccessible::ObjectCreated) {
|
||||
// qDebug() << "ObjectCreated" << object << name;
|
||||
populateAccessibilityScene(interface, 0, m_scene);
|
||||
}
|
||||
|
||||
QGraphicsRectItem *item = m_graphicsItems.value(object);
|
||||
|
||||
if (!item) {
|
||||
// qDebug() << "populateAccessibilityScene failed for" << object;
|
||||
return;
|
||||
}
|
||||
|
||||
if (reason == QAccessible::LocationChanged) {
|
||||
|
||||
//if (name.startsWith("List"))
|
||||
qDebug() << "locationChange" << object << name << interface->rect(0);
|
||||
|
||||
updateItem(item, interface);
|
||||
for (int i = 0; i < interface->childCount(); ++i) {
|
||||
QAccessibleInterface *child = 0;
|
||||
int ret = interface->navigate(QAccessible::Child, i + 1, &child);
|
||||
if (ret == 0 && child) {
|
||||
updateItem(m_graphicsItems.value(child->object()), child);
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
delete interface;
|
||||
} else if (reason == QAccessible::ObjectDestroyed) {
|
||||
// qDebug() << "ObjectDestroyed" << object << name;
|
||||
delete m_graphicsItems.value(object);
|
||||
m_graphicsItems.remove(object);
|
||||
m_animatedObjects.remove(object);
|
||||
if (object == m_selectedObject) {
|
||||
m_selectedObject = 0;
|
||||
}
|
||||
} else if (reason == QAccessible::ObjectHide) {
|
||||
// qDebug() << "ObjectCreated Hide" << object;
|
||||
updateItemFlags(item, interface);
|
||||
} else if (reason == QAccessible::ObjectShow) {
|
||||
// qDebug() << "ObjectCreated Show" << object;
|
||||
updateItemFlags(item, interface);
|
||||
} else if (reason == QAccessible::ScrollingStart) {
|
||||
qDebug() << "ObjectCreated ScrollingStart" << object;
|
||||
QAccessibleInterface *child = 0;
|
||||
for (int i = 0; i < interface->childCount(); ++i) {
|
||||
int ret = interface->navigate(QAccessible::Child, i + 1, &child);
|
||||
if (ret == 0 && child) {
|
||||
m_animatedObjects.insert(child->object());
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
} else if (reason == QAccessible::ScrollingEnd) {
|
||||
// qDebug() << "ObjectCreated ScrollingEnd" << object;
|
||||
foreach (QObject *object, m_animatedObjects) {
|
||||
updateItem(m_graphicsItems.value(object), interface);
|
||||
}
|
||||
delete interface;
|
||||
m_animatedObjects.clear();
|
||||
|
||||
} else {
|
||||
qDebug() << "other update" << object;
|
||||
}
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::setSelected(QObject *object)
|
||||
{
|
||||
m_scene->update(); // scedule update
|
||||
|
||||
// clear existing selection
|
||||
if (m_selectedObject) {
|
||||
QObject *previousSelectedObject = m_selectedObject;
|
||||
m_selectedObject = 0;
|
||||
updateItem(previousSelectedObject);
|
||||
}
|
||||
|
||||
m_selectedObject = object;
|
||||
updateItem(object);
|
||||
|
||||
populateAccessibilityTreeScene();
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::changeScale(int)
|
||||
{
|
||||
// No QGraphicsView::setScale :(
|
||||
|
||||
//m_view->scale(scale / 10.0, scale / 10.0);
|
||||
//if (m_rootItem)
|
||||
// m_view->ensureVisible(m_rootItem);
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::updateItems(QObject *root)
|
||||
{
|
||||
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(root);
|
||||
if (!interface)
|
||||
return;
|
||||
updateItem(m_graphicsItems.value(root), interface);
|
||||
|
||||
for (int i = 0; i < interface->childCount(); ++i) {
|
||||
QAccessibleInterface *child = interface->child(i);
|
||||
updateItems(child->object());
|
||||
delete child;
|
||||
}
|
||||
|
||||
delete interface;
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::updateItem(QObject *object)
|
||||
{
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
updateItem(m_graphicsItems.value(object), interface);
|
||||
|
||||
delete interface;
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::updateItem(QGraphicsRectItem *item, QAccessibleInterface *interface)
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QRect rect = interface->rect(0);
|
||||
item->setPos(rect.topLeft());
|
||||
item->setRect(QRect(QPoint(0,0), rect.size()));
|
||||
|
||||
updateItemFlags(item, interface);
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::updateItemFlags(QGraphicsRectItem *item, QAccessibleInterface *interface)
|
||||
{
|
||||
// qDebug() << "udpateItemFlags" << interface << interface->object();
|
||||
|
||||
bool shouldShow = true;
|
||||
|
||||
if (m_optionsWidget->hideInvisibleItems()) {
|
||||
if (isHidden(interface)) {
|
||||
shouldShow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_optionsWidget->hideOffscreenItems()) {
|
||||
if (interface->state(0) & QAccessible::Offscreen) {
|
||||
shouldShow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_optionsWidget->hidePaneItems()) {
|
||||
if (interface->role(0) & QAccessible::Pane) {
|
||||
shouldShow = false;
|
||||
}
|
||||
}
|
||||
|
||||
item->setVisible(shouldShow);
|
||||
|
||||
if (interface->object() == m_selectedObject)
|
||||
item->setBrush(QColor(Qt::yellow));
|
||||
else
|
||||
item->setBrush(QColor(Qt::white));
|
||||
|
||||
m_view->update();
|
||||
}
|
||||
|
||||
QGraphicsRectItem * AccessibilitySceneManager::processInterface(QAccessibleInterface * interface, int child, QGraphicsScene *scene)
|
||||
{
|
||||
// Process this interface
|
||||
|
||||
QGraphicsRectItem * item = new QGraphicsRectItem();
|
||||
scene->addItem(item);
|
||||
if (!m_rootItem)
|
||||
m_rootItem = item;
|
||||
|
||||
QString name = interface->text(QAccessibleInterface::Name, child);
|
||||
QString description; // = interface->text(QAccessibleInterface::Description, child);
|
||||
QString role = translateRole(interface->role(child));
|
||||
int childCount = interface->childCount();
|
||||
|
||||
/* qDebug() << "name:" << name << "local pos" <<
|
||||
interface->rect(0) << "description" << description << "childCount" << childCount;
|
||||
*/
|
||||
|
||||
updateItem(item, interface);
|
||||
|
||||
QGraphicsSimpleTextItem * textItem = new QGraphicsSimpleTextItem();
|
||||
textItem->setParentItem(item);
|
||||
textItem->setPos(QPoint(5, 5));
|
||||
|
||||
QString text;
|
||||
text.append("Name: " + name + " ");
|
||||
if (!description.isEmpty())
|
||||
text.append("Description: " + description + " ");
|
||||
text.append("Role: " + role + " ");
|
||||
if (childCount > 0)
|
||||
text.append("ChildCount: " + QString::number(childCount) + " ");
|
||||
textItem->setText(text);
|
||||
|
||||
QFont font;
|
||||
font.setPointSize(10);
|
||||
// font.setPointSize(14);
|
||||
textItem->setFont(font);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::populateAccessibilityScene(QAccessibleInterface * interface, int child, QGraphicsScene *scene)
|
||||
{
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
QGraphicsRectItem *item = processInterface(interface, child, scene);
|
||||
|
||||
QObject *object = interface->object();
|
||||
if (object) {
|
||||
m_graphicsItems.insert(object, item);
|
||||
}
|
||||
|
||||
// Possibly process children
|
||||
if (child != 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < interface->childCount(); ++i) {
|
||||
QAccessibleInterface *child = interface->child(i);
|
||||
updateItems(child->object());
|
||||
populateAccessibilityScene(child, 0, scene);
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
AccessibilitySceneManager::TreeItem AccessibilitySceneManager::computeLevels(QAccessibleInterface * interface, int level)
|
||||
{
|
||||
if (interface == 0)
|
||||
return TreeItem();
|
||||
|
||||
TreeItem currentLevel;
|
||||
|
||||
int usedChildren = 0;
|
||||
for (int i = 0; i < interface->childCount(); ++i) {
|
||||
QAccessibleInterface *child = interface->child(i);
|
||||
if (child != 0) {
|
||||
++usedChildren;
|
||||
TreeItem childLevel = computeLevels(child, level + 1);
|
||||
currentLevel.children.append(childLevel);
|
||||
currentLevel.width += childLevel.width + m_treeItemHorizontalPadding;
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
// leaf node case
|
||||
if (usedChildren == 0) {
|
||||
currentLevel.width = m_treeItemWidth + m_treeItemHorizontalPadding;
|
||||
}
|
||||
|
||||
// capture information:
|
||||
currentLevel.name = interface->text(QAccessible::Name, 0);
|
||||
//currentLevel.description += interface->text(QAccessible::DebugDescription, 0);
|
||||
currentLevel.role = translateRole(interface->role(0));
|
||||
currentLevel.rect = interface->rect(0);
|
||||
currentLevel.state = interface->state(0);
|
||||
currentLevel.object = interface->object();
|
||||
|
||||
return currentLevel;
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::populateAccessibilityTreeScene(QAccessibleInterface * interface, int child)
|
||||
{
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
// set some layout metrics:
|
||||
m_treeItemWidth = 90;
|
||||
m_treeItemHorizontalPadding = 10;
|
||||
m_treeItemHeight = 60;
|
||||
m_treeItemVerticalPadding = 30;
|
||||
|
||||
// We want to draw the accessibility hiearchy as a vertical
|
||||
// tree, growing from the root node at the top.
|
||||
|
||||
// First, figure out the number of levels and the width of each level:
|
||||
m_rootTreeItem = computeLevels(interface, 0);
|
||||
|
||||
// create graphics items for each tree item
|
||||
addGraphicsItems(m_rootTreeItem, 0, 0);
|
||||
}
|
||||
|
||||
void AccessibilitySceneManager::addGraphicsItems(AccessibilitySceneManager::TreeItem item, int row, int xPos)
|
||||
{
|
||||
//qDebug() << "add graphics item" << row << item.name << item.role << xPos << item.width << item.children.count();
|
||||
|
||||
int yPos = row * (m_treeItemHeight + m_treeItemVerticalPadding);
|
||||
|
||||
// Process this interface
|
||||
QGraphicsRectItem * graphicsItem = new QGraphicsRectItem();
|
||||
graphicsItem->setPos(xPos, yPos);
|
||||
graphicsItem->setRect(0, 0, m_treeItemWidth, m_treeItemHeight);
|
||||
graphicsItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
|
||||
|
||||
if (item.object == m_selectedObject)
|
||||
graphicsItem->setBrush(QColor(Qt::yellow));
|
||||
else
|
||||
graphicsItem->setBrush(QColor(Qt::white));
|
||||
|
||||
if (item.state & QAccessible::Invisible) {
|
||||
QPen linePen;
|
||||
linePen.setStyle(Qt::DashLine);
|
||||
graphicsItem->setPen(linePen);
|
||||
}
|
||||
|
||||
m_treeScene->addItem(graphicsItem);
|
||||
|
||||
QGraphicsTextItem * textItem = new QGraphicsTextItem();
|
||||
textItem->setParentItem(graphicsItem);
|
||||
textItem->setPos(QPoint(0, 0));
|
||||
|
||||
QFont font;
|
||||
font.setPointSize(8);
|
||||
textItem->setFont(font);
|
||||
|
||||
QString text;
|
||||
text += item.name + "\n";
|
||||
text += item.role + "\n";
|
||||
text += item.description.split(" ", QString::SkipEmptyParts).join("\n") + "\n";
|
||||
text += "P:" + QString::number(item.rect.x()) + " " + QString::number(item.rect.y()) + " ";
|
||||
text += "S:" + QString::number(item.rect.width()) + " " + QString::number(item.rect.height()) + "\n";
|
||||
|
||||
textItem->setPlainText(text);
|
||||
|
||||
// recurse to children
|
||||
int childIndex = 0;
|
||||
int childCount = item.children.count();
|
||||
int segmentSize = item.width / qMax(1, childCount);
|
||||
int segmentCenterOffset = segmentSize / 2;
|
||||
int segmentsStart = xPos - (item.width / 2);
|
||||
foreach (TreeItem child, item.children) {
|
||||
// spread the children out, covering the width, centered on xPos
|
||||
int segmentPosition = segmentsStart + (segmentSize * childIndex) + segmentCenterOffset;
|
||||
addGraphicsItems(child, row + 1, segmentPosition);
|
||||
++childIndex;
|
||||
}
|
||||
|
||||
// add lines from parents to kids
|
||||
int boxBottom = yPos + m_treeItemHeight;
|
||||
int boxMiddleX = xPos + m_treeItemWidth / 2;
|
||||
int yBottomMiddle = boxBottom + m_treeItemVerticalPadding / 2;
|
||||
int boxTop = yPos;
|
||||
int yTopMiddle = boxTop - m_treeItemVerticalPadding / 2;
|
||||
|
||||
if (row > 0) {
|
||||
QGraphicsLineItem *childVerticalStem = new QGraphicsLineItem();
|
||||
childVerticalStem->setLine(boxMiddleX, yTopMiddle, boxMiddleX, boxTop);
|
||||
m_treeScene->addItem(childVerticalStem);
|
||||
}
|
||||
|
||||
if (childCount > 0) {
|
||||
QGraphicsLineItem *parentVerticalStem = new QGraphicsLineItem();
|
||||
parentVerticalStem->setLine(boxMiddleX, boxBottom, boxMiddleX, yBottomMiddle);
|
||||
m_treeScene->addItem(parentVerticalStem);
|
||||
}
|
||||
|
||||
if (childCount > 1) {
|
||||
QGraphicsLineItem *horizontalStem = new QGraphicsLineItem();
|
||||
// match the end points with the horizontal lines
|
||||
int lineStartX = segmentsStart + segmentCenterOffset + m_treeItemWidth / 2;
|
||||
int lineStopX = segmentsStart + segmentSize * (childCount -1) + segmentCenterOffset + m_treeItemWidth / 2;
|
||||
horizontalStem->setLine(lineStartX, yBottomMiddle, lineStopX , yBottomMiddle);
|
||||
m_treeScene->addItem(horizontalStem);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccessibilitySceneManager::isHidden(QAccessibleInterface *interface)
|
||||
{
|
||||
QAccessibleInterface *current = interface;
|
||||
while (current) {
|
||||
|
||||
if (current->state(0) & QAccessible::Invisible) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QAccessibleInterface *parent = current->parent();
|
||||
|
||||
if (current != interface)
|
||||
delete current;
|
||||
current = parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
117
tools/accessibilityinspector/accessibilityscenemanager.h
Normal file
117
tools/accessibilityinspector/accessibilityscenemanager.h
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ACCESSIBILITYSCENEMANAGER_H
|
||||
#define ACCESSIBILITYSCENEMANAGER_H
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
#include "optionswidget.h"
|
||||
|
||||
QString translateRole(QAccessible::Role role);
|
||||
class AccessibilitySceneManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AccessibilitySceneManager();
|
||||
void setRootWindow(QWindow * window) { m_window = window; }
|
||||
void setView(QGraphicsView *view) { m_view = view; }
|
||||
void setScene(QGraphicsScene *scene) { m_scene = scene; }
|
||||
void setTreeView(QGraphicsView *treeView) { m_treeView = treeView; }
|
||||
void setTreeScene(QGraphicsScene *treeScene) { m_treeScene = treeScene; }
|
||||
|
||||
void setOptionsWidget(OptionsWidget *optionsWidget) { m_optionsWidget = optionsWidget; }
|
||||
public slots:
|
||||
void populateAccessibilityScene();
|
||||
void updateAccessibilitySceneItemFlags();
|
||||
void populateAccessibilityTreeScene();
|
||||
void handleUpdate(QObject *object, QAccessible::Event reason);
|
||||
void setSelected(QObject *object);
|
||||
|
||||
void changeScale(int scale);
|
||||
private:
|
||||
void updateItems(QObject *root);
|
||||
void updateItem(QObject *object);
|
||||
void updateItem(QGraphicsRectItem *item, QAccessibleInterface *interface);
|
||||
void updateItemFlags(QGraphicsRectItem *item, QAccessibleInterface *interface);
|
||||
|
||||
void populateAccessibilityScene(QAccessibleInterface * interface, int child, QGraphicsScene *scene);
|
||||
QGraphicsRectItem * processInterface(QAccessibleInterface * interface, int child, QGraphicsScene *scene);
|
||||
|
||||
struct TreeItem;
|
||||
TreeItem computeLevels(QAccessibleInterface * interface, int level);
|
||||
void populateAccessibilityTreeScene(QAccessibleInterface * interface, int child);
|
||||
void addGraphicsItems(TreeItem item, int row, int xPos);
|
||||
|
||||
bool isHidden(QAccessibleInterface *interface);
|
||||
|
||||
QWindow *m_window;
|
||||
QGraphicsView *m_view;
|
||||
QGraphicsScene *m_scene;
|
||||
QGraphicsView *m_treeView;
|
||||
QGraphicsScene *m_treeScene;
|
||||
QGraphicsItem *m_rootItem;
|
||||
OptionsWidget *m_optionsWidget;
|
||||
QObject *m_selectedObject;
|
||||
|
||||
QHash<QObject *, QGraphicsRectItem*> m_graphicsItems;
|
||||
QSet<QObject *> m_animatedObjects;
|
||||
|
||||
struct TreeItem {
|
||||
QList<TreeItem> children;
|
||||
int width;
|
||||
QString name;
|
||||
QString role;
|
||||
QString description;
|
||||
QRect rect;
|
||||
QAccessible::State state;
|
||||
QObject *object;
|
||||
TreeItem() : width(0) {}
|
||||
};
|
||||
|
||||
TreeItem m_rootTreeItem;
|
||||
int m_treeItemWidth;
|
||||
int m_treeItemHorizontalPadding;
|
||||
int m_treeItemHeight;
|
||||
int m_treeItemVerticalPadding;
|
||||
};
|
||||
|
||||
#endif // ACCESSIBILITYSCENEMANAGER_H
|
119
tools/accessibilityinspector/main.cpp
Normal file
119
tools/accessibilityinspector/main.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtDeclarative/QtDeclarative>
|
||||
#include <QtUiTools/QtUiTools>
|
||||
|
||||
#include "accessibilityinspector.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
if (app.arguments().count() < 2) {
|
||||
qDebug() << "Usage: accessebilityInspector [ ui-file | qml-file ] [Option]";
|
||||
qDebug() << "Option:";
|
||||
#ifdef QT_ACCESSIBILITY_INSPECTOR_SCENE_GRAPH
|
||||
qDebug() << "-qtquick1: Use QDeclarativeView instead of QSGView for rendering QML files";
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString fileName = app.arguments().at(1);
|
||||
QString mode;
|
||||
if (app.arguments().count() > 2) {
|
||||
mode = app.arguments().at(2);
|
||||
}
|
||||
|
||||
QWidget *window;
|
||||
|
||||
if (fileName.endsWith(".ui")) {
|
||||
QUiLoader loader;
|
||||
QFile file(fileName);
|
||||
file.open(QFile::ReadOnly);
|
||||
window = loader.load(&file, 0);
|
||||
} else if (fileName.endsWith(".qml")){
|
||||
QUrl fileUrl;
|
||||
if (fileName.startsWith(":")) { // detect resources.
|
||||
QString name = fileName;
|
||||
name.remove(0, 2); // reomve ":/"
|
||||
fileUrl.setUrl(QLatin1String("qrc:/") + name);
|
||||
} else {
|
||||
fileUrl = QUrl::fromLocalFile(fileName);
|
||||
}
|
||||
|
||||
#ifdef QT_ACCESSIBILITY_INSPECTOR_SCENE_GRAPH
|
||||
if (mode == QLatin1String("-qtquick1"))
|
||||
#endif
|
||||
{
|
||||
QDeclarativeView * declarativeView = new QDeclarativeView();
|
||||
declarativeView->setSource(fileUrl);
|
||||
window = declarativeView;
|
||||
}
|
||||
#ifdef QT_ACCESSIBILITY_INSPECTOR_SCENE_GRAPH
|
||||
else {
|
||||
QSGView * sceneGraphView = new QSGView();
|
||||
sceneGraphView->setSource(fileUrl);
|
||||
window = sceneGraphView;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
qDebug() << "Error: don't know what to do with" << fileName;
|
||||
}
|
||||
|
||||
AccessibilityInspector *accessibilityInspector = new AccessibilityInspector();
|
||||
|
||||
accessibilityInspector->inspectWindow(window);
|
||||
|
||||
window->move(50, 50);
|
||||
window->show();
|
||||
|
||||
int ret = app.exec();
|
||||
|
||||
accessibilityInspector->saveWindowGeometry();
|
||||
delete accessibilityInspector;
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
43
tools/accessibilityinspector/optionswidget.cpp
Normal file
43
tools/accessibilityinspector/optionswidget.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "optionswidget.h"
|
||||
|
117
tools/accessibilityinspector/optionswidget.h
Normal file
117
tools/accessibilityinspector/optionswidget.h
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef OPTIONSWIDGET_H
|
||||
#define OPTIONSWIDGET_H
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
|
||||
class OptionsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OptionsWidget()
|
||||
:QWidget()
|
||||
{
|
||||
QVBoxLayout *m_layout = new QVBoxLayout;
|
||||
|
||||
m_refresh = new QPushButton(this);
|
||||
m_refresh->setText(QLatin1String("Refresh"));
|
||||
m_layout->addWidget(m_refresh);
|
||||
connect(m_refresh, SIGNAL(clicked()), SIGNAL(refreshClicked()));
|
||||
|
||||
m_hideInvisibleItems = new QCheckBox(this);
|
||||
m_layout->addWidget(m_hideInvisibleItems);
|
||||
m_hideInvisibleItems->setText("Hide Invisible Items");
|
||||
m_hideInvisibleItems->setChecked(true);
|
||||
connect(m_hideInvisibleItems, SIGNAL(toggled(bool)), SIGNAL(optionsChanged()));
|
||||
|
||||
m_hideOffscreenItems = new QCheckBox(this);
|
||||
m_layout->addWidget(m_hideOffscreenItems);
|
||||
m_hideOffscreenItems->setText("Hide Offscreen Items");
|
||||
m_hideOffscreenItems->setChecked(true);
|
||||
connect(m_hideOffscreenItems, SIGNAL(toggled(bool)), SIGNAL(optionsChanged()));
|
||||
|
||||
m_hidePaneItems = new QCheckBox(this);
|
||||
m_layout->addWidget(m_hidePaneItems);
|
||||
m_hidePaneItems->setText("Hide Items with the Pane role");
|
||||
m_hidePaneItems->setChecked(true);
|
||||
connect(m_hidePaneItems, SIGNAL(toggled(bool)), SIGNAL(optionsChanged()));
|
||||
|
||||
m_enableTextToSpeach = new QCheckBox(this);
|
||||
m_layout->addWidget(m_enableTextToSpeach);
|
||||
m_enableTextToSpeach->setText("Enable Text To Speech");
|
||||
m_enableTextToSpeach->setChecked(false);
|
||||
connect(m_enableTextToSpeach, SIGNAL(toggled(bool)), SIGNAL(optionsChanged()));
|
||||
|
||||
|
||||
m_scale = new QSlider(Qt::Horizontal);
|
||||
// m_layout->addWidget(m_scale);
|
||||
m_scale->setRange(5, 30);
|
||||
m_scale->setValue(1);
|
||||
connect(m_scale, SIGNAL(valueChanged(int)), SIGNAL(scaleChanged(int)));
|
||||
|
||||
this->setLayout(m_layout);
|
||||
}
|
||||
|
||||
bool hideInvisibleItems() { return m_hideInvisibleItems->isChecked(); }
|
||||
bool hideOffscreenItems() { return m_hideOffscreenItems->isChecked(); }
|
||||
bool hidePaneItems() { return m_hidePaneItems->isChecked(); }
|
||||
bool enableTextToSpeach() { return m_enableTextToSpeach->isChecked(); }
|
||||
signals:
|
||||
void optionsChanged();
|
||||
void refreshClicked();
|
||||
void scaleChanged(int);
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_layout;
|
||||
|
||||
QPushButton *m_refresh;
|
||||
QCheckBox *m_hideInvisibleItems;
|
||||
QCheckBox *m_hideOffscreenItems;
|
||||
QCheckBox *m_hidePaneItems;
|
||||
QCheckBox *m_enableTextToSpeach;
|
||||
QSlider *m_scale;
|
||||
};
|
||||
|
||||
|
||||
#endif // OPTIONSWIDGET_H
|
162
tools/accessibilityinspector/screenreader.cpp
Normal file
162
tools/accessibilityinspector/screenreader.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "screenreader.h"
|
||||
#include "optionswidget.h"
|
||||
#include "accessibilityscenemanager.h"
|
||||
#include <QtGui>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <private/qt_mac_p.h>
|
||||
#endif
|
||||
|
||||
ScreenReader::ScreenReader(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
m_selectedInterface = 0;
|
||||
m_rootInterface = 0;
|
||||
bool activateCalled = false;
|
||||
}
|
||||
|
||||
ScreenReader::~ScreenReader()
|
||||
{
|
||||
delete m_selectedInterface;
|
||||
delete m_rootInterface;
|
||||
}
|
||||
|
||||
void ScreenReader::setRootObject(QObject *rootObject)
|
||||
{
|
||||
m_rootInterface = QAccessible::queryAccessibleInterface(rootObject);
|
||||
}
|
||||
|
||||
void ScreenReader::setOptionsWidget(OptionsWidget *optionsWidget)
|
||||
{
|
||||
m_optionsWidget = optionsWidget;
|
||||
}
|
||||
|
||||
void ScreenReader::touchPoint(const QPoint &point)
|
||||
{
|
||||
qDebug() << "touch" << point;
|
||||
// Wait and see if this touch is the start of a double-tap
|
||||
// (activate will then be called and cancel the touch processing)
|
||||
m_activateCalled = false;
|
||||
m_currentTouchPoint = point;
|
||||
QTimer::singleShot(200, this, SLOT(processTouchPoint()));
|
||||
}
|
||||
|
||||
void ScreenReader::processTouchPoint()
|
||||
{
|
||||
if (m_activateCalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_rootInterface == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QAccessibleInterface * currentInterface = m_rootInterface;
|
||||
|
||||
int hit = -2;
|
||||
int guardCounter = 0;
|
||||
const int guardMax = 40;
|
||||
while (hit != 0) {
|
||||
++guardCounter;
|
||||
if (guardCounter > guardMax) {
|
||||
qDebug() << "touchPoint exit recursion overflow";
|
||||
return; // outside
|
||||
}
|
||||
|
||||
hit = currentInterface->childAt(m_currentTouchPoint.x(), m_currentTouchPoint.y());
|
||||
//qDebug() << "hit" << hit;
|
||||
if (hit == -1) {
|
||||
return; // outside
|
||||
} else if (hit == 0) {
|
||||
break; // found it.
|
||||
} else {
|
||||
QAccessibleInterface *childInterface = 0;
|
||||
int child = currentInterface->navigate(QAccessible::Child, hit, &childInterface);
|
||||
if (childInterface == 0) {
|
||||
return; // navigation error
|
||||
}
|
||||
|
||||
if (currentInterface != m_rootInterface)
|
||||
delete currentInterface;
|
||||
currentInterface = childInterface;
|
||||
}
|
||||
}
|
||||
|
||||
m_selectedInterface = currentInterface;
|
||||
emit selected(m_selectedInterface->object());
|
||||
if (m_optionsWidget->enableTextToSpeach())
|
||||
speak(m_selectedInterface->text(QAccessible::Name, 0)
|
||||
/*+ "," + translateRole(m_selectedInterface->role(0)) */);
|
||||
|
||||
// qDebug() << "touchPoint exit found" << m_selectedInterface->text(QAccessible::Name, 0) << m_selectedInterface->object() << m_selectedInterface->rect(0);
|
||||
}
|
||||
|
||||
void ScreenReader::activate()
|
||||
{
|
||||
qDebug() << "ScreenReader::activate";
|
||||
m_activateCalled = true;
|
||||
if (m_selectedInterface) {
|
||||
m_selectedInterface->doAction(QAccessible::Press, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
// screenreader.mm
|
||||
|
||||
#else
|
||||
|
||||
void ScreenReader::speak(const QString &text, const QString &/*voice*/)
|
||||
{
|
||||
QFile f("festivalspeachhack");
|
||||
f.open(QIODevice::WriteOnly);
|
||||
f.write(text.toLocal8Bit());
|
||||
f.close();
|
||||
|
||||
QProcess *process = new QProcess;
|
||||
process->start("/usr/bin/festival", QStringList() << "--tts" << "festivalspeachhack");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
84
tools/accessibilityinspector/screenreader.h
Normal file
84
tools/accessibilityinspector/screenreader.h
Normal file
@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef SCREENREADER_H
|
||||
#define SCREENREADER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAccessible>
|
||||
#include <QAccessibleBridge>
|
||||
|
||||
/*
|
||||
A Simple screen reader for touch-based user interfaces.
|
||||
|
||||
Requires a text-to-speach backend. Currently implemented on
|
||||
Mac OS X and using festival on unix.
|
||||
*/
|
||||
class OptionsWidget;
|
||||
class ScreenReader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScreenReader(QObject *parent = 0);
|
||||
~ScreenReader();
|
||||
|
||||
void setRootObject(QObject *rootObject);
|
||||
void setOptionsWidget(OptionsWidget *optionsWidget);
|
||||
public slots:
|
||||
void touchPoint(const QPoint &point);
|
||||
void activate();
|
||||
protected slots:
|
||||
void processTouchPoint();
|
||||
signals:
|
||||
void selected(QObject *object);
|
||||
|
||||
protected:
|
||||
void speak(const QString &text, const QString &voice = QString());
|
||||
private:
|
||||
QAccessibleInterface *m_selectedInterface;
|
||||
QAccessibleInterface *m_rootInterface;
|
||||
OptionsWidget *m_optionsWidget;
|
||||
QPoint m_currentTouchPoint;
|
||||
bool m_activateCalled;
|
||||
};
|
||||
|
||||
#endif // SCREENREADER_H
|
60
tools/accessibilityinspector/screenreader_mac.mm
Normal file
60
tools/accessibilityinspector/screenreader_mac.mm
Normal file
@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "screenreader.h"
|
||||
#include <QtCore>
|
||||
#include <private/qt_mac_p.h>
|
||||
|
||||
void ScreenReader::speak(const QString &text, const QString &voice)
|
||||
{
|
||||
QString voiceBase = "com.apple.speech.synthesis.voice.";
|
||||
if (voice.isEmpty())
|
||||
voiceBase += "Vici";
|
||||
else
|
||||
voiceBase += voice;
|
||||
|
||||
CFStringRef cfVoice = QCFString::toCFStringRef(voiceBase);
|
||||
NSSpeechSynthesizer *synth = [[NSSpeechSynthesizer alloc] initWithVoice:(NSString *)cfVoice];
|
||||
CFStringRef cfText = QCFString::toCFStringRef(text);
|
||||
[synth startSpeakingString: (NSString *)cfText];
|
||||
CFRelease(cfText);
|
||||
CFRelease(cfVoice);
|
||||
}
|
Loading…
Reference in New Issue
Block a user