Remove Qt4 Mac accessibility backend files.
Change-Id: I2c41050b5965756ae4c2ecfe73ba5926880ed98d Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
This commit is contained in:
parent
d6fb349751
commit
1f7aa83661
@ -16,16 +16,4 @@ contains(QT_CONFIG, accessibility) {
|
||||
|
||||
HEADERS += accessible/qaccessiblebridge.h
|
||||
SOURCES += accessible/qaccessiblebridge.cpp
|
||||
|
||||
### FIXME
|
||||
# mac:!qpa {
|
||||
# HEADERS += accessible/qaccessible_mac_p.h
|
||||
# OBJECTIVE_SOURCES += accessible/qaccessible_mac.mm \
|
||||
# accessible/qaccessible_mac_cocoa.mm
|
||||
# } else:win32:!qpa {
|
||||
# SOURCES += accessible/qaccessible_win.cpp
|
||||
# } else {
|
||||
# HEADERS += accessible/qaccessiblebridge.h
|
||||
# SOURCES += accessible/qaccessible_unix.cpp accessible/qaccessiblebridge.cpp
|
||||
# }
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,119 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
static OSStatus applicationEventHandler(EventHandlerCallRef next_ref, EventRef event, void *data);
|
||||
static EventHandlerUPP applicationEventHandlerUPP = 0;
|
||||
static EventTypeSpec application_events[] = {
|
||||
{ kEventClassAccessibility, kEventAccessibleGetChildAtPoint },
|
||||
{ kEventClassAccessibility, kEventAccessibleGetNamedAttribute }
|
||||
};
|
||||
|
||||
static CFStringRef kObjectQtAccessibility = CFSTR("com.trolltech.qt.accessibility");
|
||||
static EventHandlerUPP objectCreateEventHandlerUPP = 0;
|
||||
static EventTypeSpec objectCreateEvents[] = {
|
||||
{ kEventClassHIObject, kEventHIObjectConstruct },
|
||||
{ kEventClassHIObject, kEventHIObjectInitialize },
|
||||
{ kEventClassHIObject, kEventHIObjectDestruct },
|
||||
{ kEventClassHIObject, kEventHIObjectPrintDebugInfo }
|
||||
};
|
||||
|
||||
static OSStatus accessibilityEventHandler(EventHandlerCallRef next_ref, EventRef event, void *data);
|
||||
static EventHandlerUPP accessibilityEventHandlerUPP = 0;
|
||||
static EventTypeSpec accessibilityEvents[] = {
|
||||
{ kEventClassAccessibility, kEventAccessibleGetChildAtPoint },
|
||||
{ kEventClassAccessibility, kEventAccessibleGetFocusedChild },
|
||||
{ kEventClassAccessibility, kEventAccessibleGetAllAttributeNames },
|
||||
{ kEventClassAccessibility, kEventAccessibleGetNamedAttribute },
|
||||
{ kEventClassAccessibility, kEventAccessibleSetNamedAttribute },
|
||||
{ kEventClassAccessibility, kEventAccessibleIsNamedAttributeSettable },
|
||||
{ kEventClassAccessibility, kEventAccessibleGetAllActionNames },
|
||||
{ kEventClassAccessibility, kEventAccessiblePerformNamedAction },
|
||||
{ kEventClassAccessibility, kEventAccessibleGetNamedActionDescription }
|
||||
};
|
||||
|
||||
static void installAcessibilityEventHandler(HIObjectRef hiObject)
|
||||
{
|
||||
if (!accessibilityEventHandlerUPP)
|
||||
accessibilityEventHandlerUPP = NewEventHandlerUPP(accessibilityEventHandler);
|
||||
|
||||
InstallHIObjectEventHandler(hiObject, accessibilityEventHandlerUPP,
|
||||
GetEventTypeCount(accessibilityEvents),
|
||||
accessibilityEvents, 0, 0);
|
||||
}
|
||||
|
||||
static OSStatus objectCreateEventHandler(EventHandlerCallRef next_ref, EventRef event, void *data)
|
||||
{
|
||||
Q_UNUSED(data)
|
||||
Q_UNUSED(event)
|
||||
Q_UNUSED(next_ref)
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static void registerQtAccessibilityHIObjectSubclass()
|
||||
{
|
||||
if (!objectCreateEventHandlerUPP)
|
||||
objectCreateEventHandlerUPP = NewEventHandlerUPP(objectCreateEventHandler);
|
||||
OSStatus err = HIObjectRegisterSubclass(kObjectQtAccessibility, 0, 0, objectCreateEventHandlerUPP,
|
||||
GetEventTypeCount(objectCreateEvents), objectCreateEvents, 0, 0);
|
||||
if (err && err != hiObjectClassExistsErr)
|
||||
qWarning("qaccessible_mac internal error: Could not register accessibility HIObject subclass");
|
||||
}
|
||||
|
||||
static void installApplicationEventhandler()
|
||||
{
|
||||
if (!applicationEventHandlerUPP)
|
||||
applicationEventHandlerUPP = NewEventHandlerUPP(applicationEventHandler);
|
||||
|
||||
OSStatus err = InstallApplicationEventHandler(applicationEventHandlerUPP,
|
||||
GetEventTypeCount(application_events), application_events,
|
||||
0, 0);
|
||||
|
||||
if (err && err != eventHandlerAlreadyInstalledErr)
|
||||
qWarning("qaccessible_mac internal error: Could not install application accessibility event handler");
|
||||
}
|
||||
|
||||
static void removeEventhandler(EventHandlerUPP eventHandler)
|
||||
{
|
||||
if (eventHandler) {
|
||||
DisposeEventHandlerUPP(eventHandler);
|
||||
eventHandler = 0;
|
||||
}
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module 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 "qaccessible.h"
|
||||
#include "qaccessible_mac_p.h"
|
||||
#include "qdebug.h"
|
||||
#include "qtabwidget.h"
|
||||
|
||||
#include <private/qt_mac_p.h>
|
||||
#include <private/qcocoaview_mac_p.h>
|
||||
#include <private/qwidget_p.h>
|
||||
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#ifdef QT_MAC_USE_COCOA
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
//#define MAC_ACCESSIBILTY_DEVELOPER_MODE
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#ifdef MAC_ACCESSIBILTY_DEVELOPER_MODE
|
||||
#define MAC_ACCESSIBILTY_DEBUG QT_PREPEND_NAMESPACE(qDebug)
|
||||
#else
|
||||
#define MAC_ACCESSIBILTY_DEBUG if (0) QT_PREPEND_NAMESPACE(qDebug)
|
||||
#endif
|
||||
#else
|
||||
#define MAC_ACCESSIBILTY_DEBUG if (0) QT_PREPEND_NAMESPACE(QNoDebug)
|
||||
#endif
|
||||
|
||||
typedef QMap<QAccessible::Role, NSString *> QMacAccessibiltyRoleMap;
|
||||
Q_GLOBAL_STATIC(QMacAccessibiltyRoleMap, qMacAccessibiltyRoleMap);
|
||||
|
||||
static QAInterface interfaceForView(QT_MANGLE_NAMESPACE(QCocoaView) *view)
|
||||
{
|
||||
return QAInterface(QAccessible::queryAccessibleInterface([view qt_qwidget]));
|
||||
}
|
||||
|
||||
/*
|
||||
Set up mappings from Qt accessibilty roles to Mac accessibilty roles.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a Mac accessibility role for the given interface, or
|
||||
NSAccessibilityUnknownRole if no role mapping is found.
|
||||
*/
|
||||
static NSString *macRoleForInterface(QAInterface interface)
|
||||
{
|
||||
const QAccessible::Role qtRole = interface.role();
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
Is the interface a QTabBar embedded in a QTabWidget?
|
||||
(as opposed to a stand-alone tab bar)
|
||||
*/
|
||||
static bool isEmbeddedTabBar(const QAInterface &interface)
|
||||
{
|
||||
QObject *object = interface.object();
|
||||
if (interface.role() == QAccessible::PageTabList && object)
|
||||
return (qobject_cast<QTabWidget *>(object->parent()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isInterfaceIgnored(QAInterface interface)
|
||||
{
|
||||
// Mac accessibility does not have an attribute that corresponds to the
|
||||
// Invisible/Offscreen state. Use the ignore facility to disable them.
|
||||
const QAccessible::State state = interface.state();
|
||||
if (state & QAccessible::Invisible ||
|
||||
state & QAccessible::Offscreen )
|
||||
return false;
|
||||
|
||||
// Hide QTabBars that has a QTabWidget parent (the QTabWidget handles the accessibility)
|
||||
if (isEmbeddedTabBar(interface))
|
||||
return false;
|
||||
|
||||
if (QObject * const object = interface.object()) {
|
||||
const QString className = QLatin1String(object->metaObject()->className());
|
||||
|
||||
// Prevent VoiceOver from focusing on tool tips by ignoring those
|
||||
// interfaces. Shifting VoiceOver focus to the tool tip is confusing
|
||||
// and the contents of the tool tip is avalible through the description
|
||||
// attribute anyway.
|
||||
if (className == QLatin1String("QTipLabel"))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide interfaces with an unknown role. When developing it's often useful to disable
|
||||
// this check to see all interfaces in the hierarchy.
|
||||
#ifndef MAC_ACCESSIBILTY_DEVELOPER_MODE
|
||||
return [macRoleForInterface(interface) isEqualToString: NSAccessibilityUnknownRole];
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@implementation QT_MANGLE_NAMESPACE(QCocoaView) (Accessibility)
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
QT_PREPEND_NAMESPACE(QAInterface) interface = QT_PREPEND_NAMESPACE(interfaceForView)(self);
|
||||
return isInterfaceIgnored(interface);
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityAttributeNames
|
||||
{
|
||||
QT_PREPEND_NAMESPACE(QAInterface) interface = QT_PREPEND_NAMESPACE(interfaceForView)(self);
|
||||
|
||||
static NSArray *attributes = nil;
|
||||
if (attributes == nil) {
|
||||
attributes = [super accessibilityAttributeNames];
|
||||
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
MAC_ACCESSIBILTY_DEBUG() << "accessibilityAttributeValue" << self <<
|
||||
QT_PREPEND_NAMESPACE(QCFString)::toQString(reinterpret_cast<CFStringRef>(attribute));
|
||||
|
||||
QT_PREPEND_NAMESPACE(QAInterface) interface = QT_PREPEND_NAMESPACE(interfaceForView)(self);
|
||||
|
||||
// Switch on the attribute name and call the appropriate handler function.
|
||||
// Pass the call on to the NSView class for attributes we don't handle.
|
||||
if ([attribute isEqualToString:@"AXRole"]) {
|
||||
return macRoleForInterface(interface);
|
||||
} else {
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // QT_MAC_USE_COCOA
|
||||
|
||||
#endif // QT_NO_ACCESSIBILITY
|
||||
|
@ -1,479 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module 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 QACCESSIBLE_MAC_P_H
|
||||
#define QACCESSIBLE_MAC_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
//
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <private/qt_mac_p.h>
|
||||
#include <qaccessible.h>
|
||||
#include <qwidget.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
//#define Q_ACCESSIBLE_MAC_DEBUG
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*
|
||||
QAccessibleInterfaceWrapper wraps QAccessibleInterface and adds
|
||||
a ref count. QAccessibleInterfaceWrapper is a "by-value" class.
|
||||
*/
|
||||
class Q_AUTOTEST_EXPORT QAccessibleInterfaceWrapper
|
||||
{
|
||||
public:
|
||||
QAccessibleInterfaceWrapper()
|
||||
: interface(0), childrenIsRegistered(new bool(false)), refCount(new int(1)) { }
|
||||
|
||||
QAccessibleInterfaceWrapper(QAccessibleInterface *interface)
|
||||
:interface(interface), childrenIsRegistered(new bool(false)), refCount(new int(1)) { }
|
||||
|
||||
~QAccessibleInterfaceWrapper()
|
||||
{
|
||||
if (--(*refCount) == 0) {
|
||||
delete interface;
|
||||
delete refCount;
|
||||
delete childrenIsRegistered;
|
||||
}
|
||||
}
|
||||
|
||||
QAccessibleInterfaceWrapper(const QAccessibleInterfaceWrapper &other)
|
||||
:interface(other.interface), childrenIsRegistered(other.childrenIsRegistered), refCount(other.refCount)
|
||||
{
|
||||
++(*refCount);
|
||||
}
|
||||
|
||||
void operator=(const QAccessibleInterfaceWrapper &other)
|
||||
{
|
||||
if (other.interface == interface)
|
||||
return;
|
||||
|
||||
if (--(*refCount) == 0) {
|
||||
delete interface;
|
||||
delete refCount;
|
||||
delete childrenIsRegistered;
|
||||
}
|
||||
|
||||
interface = other.interface;
|
||||
childrenIsRegistered = other.childrenIsRegistered;
|
||||
refCount = other.refCount;
|
||||
++(*refCount);
|
||||
}
|
||||
|
||||
QAccessibleInterface *interface;
|
||||
bool *childrenIsRegistered;
|
||||
private:
|
||||
int *refCount;
|
||||
};
|
||||
|
||||
/*
|
||||
QAInterface represents one accessiblity item. It hides the fact that
|
||||
one QAccessibleInterface may represent more than one item, and it also
|
||||
automates the memory management for QAccessibleInterfaces using the
|
||||
QAccessibleInterfaceWrapper wrapper class.
|
||||
|
||||
It has the same API as QAccessibleInterface, minus the child parameter
|
||||
in the functions.
|
||||
*/
|
||||
class Q_AUTOTEST_EXPORT QAInterface : public QAccessible
|
||||
{
|
||||
public:
|
||||
QAInterface()
|
||||
: base(QAccessibleInterfaceWrapper())
|
||||
{ }
|
||||
|
||||
QAInterface(QAccessibleInterface *interface, int child = 0)
|
||||
{
|
||||
if (interface == 0 || child > interface->childCount()) {
|
||||
base = QAccessibleInterfaceWrapper();
|
||||
} else {
|
||||
base = QAccessibleInterfaceWrapper(interface);
|
||||
m_cachedObject = interface->object();
|
||||
this->child = child;
|
||||
}
|
||||
}
|
||||
|
||||
QAInterface(QAccessibleInterfaceWrapper wrapper, int child = 0)
|
||||
:base(wrapper), m_cachedObject(wrapper.interface->object()), child(child)
|
||||
{ }
|
||||
|
||||
QAInterface(const QAInterface &other, int child)
|
||||
{
|
||||
if (other.isValid() == false || child > other.childCount()) {
|
||||
base = QAccessibleInterfaceWrapper();
|
||||
} else {
|
||||
base = other.base;
|
||||
m_cachedObject = other.m_cachedObject;
|
||||
this->child = child;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const QAInterface &other) const;
|
||||
bool operator!=(const QAInterface &other) const;
|
||||
|
||||
inline QString actionText (int action, Text text) const
|
||||
{ return base.interface->actionText(action, text, child); }
|
||||
|
||||
QAInterface childAt(int x, int y) const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QAInterface();
|
||||
|
||||
const int foundChild = base.interface->childAt(x, y);
|
||||
|
||||
if (foundChild == -1)
|
||||
return QAInterface();
|
||||
|
||||
if (child == 0)
|
||||
return navigate(QAccessible::Child, foundChild);
|
||||
|
||||
if (foundChild == child)
|
||||
return *this;
|
||||
return QAInterface();
|
||||
}
|
||||
|
||||
int indexOfChild(const QAInterface &child) const
|
||||
{
|
||||
if (!checkValid())
|
||||
return -1;
|
||||
|
||||
if (*this != child.parent())
|
||||
return -1;
|
||||
|
||||
if (object() == child.object())
|
||||
return child.id();
|
||||
|
||||
return base.interface->indexOfChild(child.base.interface);
|
||||
}
|
||||
|
||||
inline int childCount() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return 0;
|
||||
|
||||
if (child != 0)
|
||||
return 0;
|
||||
return base.interface->childCount();
|
||||
}
|
||||
|
||||
QList<QAInterface> children() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QList<QAInterface>();
|
||||
|
||||
QList<QAInterface> children;
|
||||
for (int i = 1; i <= childCount(); ++i) {
|
||||
children.append(navigate(QAccessible::Child, i));
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
QAInterface childAt(int index) const
|
||||
{
|
||||
return navigate(QAccessible::Child, index);
|
||||
}
|
||||
|
||||
inline void doAction(int action, const QVariantList ¶ms = QVariantList()) const
|
||||
{
|
||||
if (!checkValid())
|
||||
return;
|
||||
|
||||
base.interface->doAction(action, child, params);
|
||||
}
|
||||
|
||||
QAInterface navigate(RelationFlag relation, int entry) const;
|
||||
|
||||
inline QObject * object() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return 0;
|
||||
|
||||
return base.interface->object();
|
||||
}
|
||||
|
||||
QAInterface objectInterface() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QAInterface();
|
||||
|
||||
QObject *obj = object();
|
||||
QAInterface current = *this;
|
||||
while (obj == 0)
|
||||
{
|
||||
QAInterface parent = current.parent();
|
||||
if (parent.isValid() == false)
|
||||
break;
|
||||
obj = parent.object();
|
||||
current = parent;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
inline HIObjectRef hiObject() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return 0;
|
||||
QWidget * const widget = qobject_cast<QWidget * const>(object());
|
||||
if (widget)
|
||||
return (HIObjectRef)widget->winId();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline QObject * cachedObject() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return 0;
|
||||
return m_cachedObject;
|
||||
}
|
||||
|
||||
inline QRect rect() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QRect();
|
||||
return base.interface->rect(child);
|
||||
}
|
||||
|
||||
inline Role role() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QAccessible::NoRole;
|
||||
return base.interface->role(child);
|
||||
}
|
||||
|
||||
inline void setText(Text t, const QString &text) const
|
||||
{
|
||||
if (!checkValid())
|
||||
return;
|
||||
base.interface->setText(t, child, text);
|
||||
}
|
||||
|
||||
inline State state() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return 0;
|
||||
return base.interface->state(child);
|
||||
}
|
||||
|
||||
inline QString text (Text text) const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QString();
|
||||
return base.interface->text(text, child);
|
||||
}
|
||||
|
||||
inline QString value() const
|
||||
{ return text(QAccessible::Value); }
|
||||
|
||||
inline QString name() const
|
||||
{ return text(QAccessible::Name); }
|
||||
|
||||
inline int userActionCount() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return 0;
|
||||
return base.interface->userActionCount(child);
|
||||
}
|
||||
|
||||
inline QString className() const
|
||||
{
|
||||
if (!checkValid())
|
||||
return QString();
|
||||
return QLatin1String(base.interface->object()->metaObject()->className());
|
||||
}
|
||||
|
||||
inline bool isHIView() const
|
||||
{ return (child == 0 && object() != 0); }
|
||||
|
||||
inline int id() const
|
||||
{ return child; }
|
||||
|
||||
inline bool isValid() const
|
||||
{
|
||||
return (base.interface != 0 && base.interface->isValid());
|
||||
}
|
||||
|
||||
QAInterface parent() const
|
||||
{ return navigate(QAccessible::Ancestor, 1); }
|
||||
|
||||
QAccessibleInterfaceWrapper interfaceWrapper() const
|
||||
{ return base; }
|
||||
|
||||
protected:
|
||||
bool checkValid() const
|
||||
{
|
||||
const bool valid = isValid();
|
||||
#ifdef Q_ACCESSIBLE_MAC_DEBUG
|
||||
if (!valid)
|
||||
qFatal("QAccessible_mac: tried to use invalid interface.");
|
||||
#endif
|
||||
return valid;
|
||||
}
|
||||
|
||||
QAccessibleInterfaceWrapper base;
|
||||
QObject *m_cachedObject;
|
||||
int child;
|
||||
};
|
||||
|
||||
Q_AUTOTEST_EXPORT QDebug operator<<(QDebug debug, const QAInterface &interface);
|
||||
|
||||
/*
|
||||
QAElement is a thin wrapper around an AXUIElementRef that automates
|
||||
the ref-counting.
|
||||
*/
|
||||
class Q_AUTOTEST_EXPORT QAElement
|
||||
{
|
||||
public:
|
||||
QAElement();
|
||||
explicit QAElement(AXUIElementRef elementRef);
|
||||
QAElement(const QAElement &element);
|
||||
QAElement(HIObjectRef, int child);
|
||||
~QAElement();
|
||||
|
||||
inline HIObjectRef object() const
|
||||
{
|
||||
#ifndef Q_WS_MAC64
|
||||
return AXUIElementGetHIObject(elementRef);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int id() const
|
||||
{
|
||||
UInt64 theId;
|
||||
#ifndef QT_MAC_USE_COCOA
|
||||
AXUIElementGetIdentifier(elementRef, &theId);
|
||||
#else
|
||||
theId = 0;
|
||||
#endif
|
||||
return theId;
|
||||
}
|
||||
|
||||
inline AXUIElementRef element() const
|
||||
{
|
||||
return elementRef;
|
||||
}
|
||||
|
||||
inline bool isValid() const
|
||||
{
|
||||
return (elementRef != 0);
|
||||
}
|
||||
|
||||
void operator=(const QAElement &other);
|
||||
bool operator==(const QAElement &other) const;
|
||||
private:
|
||||
AXUIElementRef elementRef;
|
||||
};
|
||||
|
||||
|
||||
class QInterfaceFactory
|
||||
{
|
||||
public:
|
||||
virtual QAInterface interface(UInt64 identifier) = 0;
|
||||
virtual QAElement element(int id) = 0;
|
||||
virtual QAElement element(const QAInterface &interface)
|
||||
{
|
||||
return element(interface.id());
|
||||
}
|
||||
virtual void registerChildren() = 0;
|
||||
virtual ~QInterfaceFactory() {}
|
||||
};
|
||||
|
||||
/*
|
||||
QAccessibleHierarchyManager bridges the Mac and Qt accessibility hierarchies.
|
||||
There is a one-to-one relationship between QAElements on the Mac side
|
||||
and QAInterfaces on the Qt side, and this class provides lookup functions
|
||||
that translates between these to items.
|
||||
|
||||
The identity of a QAInterface is determined by its QAccessibleInterface and
|
||||
child identifier, and the identity of a QAElement is determined by its
|
||||
HIObjectRef and identifier.
|
||||
|
||||
QAccessibleHierarchyManager receives QObject::destroyed() signals and deletes
|
||||
the accessibility objects for destroyed objects.
|
||||
*/
|
||||
class Q_AUTOTEST_EXPORT QAccessibleHierarchyManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~QAccessibleHierarchyManager() { reset(); }
|
||||
static QAccessibleHierarchyManager *instance();
|
||||
void reset();
|
||||
|
||||
QAElement registerInterface(QObject *object, int child);
|
||||
QAElement registerInterface(const QAInterface &interface);
|
||||
void registerInterface(QObject *object, HIObjectRef hiobject, QInterfaceFactory *interfaceFactory);
|
||||
|
||||
void registerChildren(const QAInterface &interface);
|
||||
|
||||
QAInterface lookup(const AXUIElementRef &element);
|
||||
QAInterface lookup(const QAElement &element);
|
||||
QAElement lookup(const QAInterface &interface);
|
||||
QAElement lookup(QObject * const object, int id);
|
||||
private slots:
|
||||
void objectDestroyed(QObject *);
|
||||
private:
|
||||
typedef QHash<QObject *, QInterfaceFactory *> QObjectElementHash;
|
||||
typedef QHash<HIObjectRef, QInterfaceFactory *> HIObjectInterfaceHash;
|
||||
typedef QHash<QObject *, HIObjectRef> QObjectHIObjectHash;
|
||||
|
||||
QObjectElementHash qobjectElementHash;
|
||||
HIObjectInterfaceHash hiobjectInterfaceHash;
|
||||
QObjectHIObjectHash qobjectHiobjectHash;
|
||||
};
|
||||
|
||||
Q_AUTOTEST_EXPORT bool isItInteresting(const QAInterface &interface);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user