Refactor accessibility for Qt5
* Moved most stuff to gui\accessible * Moved widget-specific stuff to widgets\accessible * Moved platform-specific code to either the bridge plugin (this was already the case) or to the platform plugin. * Added several classes and functions. These have not yet gone through an API review. The plan is to do that in a later commit. Classes: - QPlatformAccessibility - QWindowsAccessibility Functions: - QWindow *QAccessibleInterface::window(); - QPlatformAccessibility *QPlatformIntegration::accessibility() * The bridge code can now either be a plugin or integrated into the platform plugin * Mac accessibility is left out for now. Unix "should still work" (tm). These platforms should be fixed soon. Change-Id: Ib49ffa73b647ee0af90864544c2769440157f562 Reviewed-on: http://codereview.qt-project.org/5330 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com> Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
This commit is contained in:
parent
8ebd7d84fc
commit
87ae97c11a
31
src/gui/accessible/accessible.pri
Normal file
31
src/gui/accessible/accessible.pri
Normal file
@ -0,0 +1,31 @@
|
||||
# Qt accessibility module
|
||||
|
||||
contains(QT_CONFIG, accessibility) {
|
||||
HEADERS += \
|
||||
accessible/qaccessible.h \
|
||||
accessible/qaccessible2.h \
|
||||
accessible/qaccessibleobject.h \
|
||||
accessible/qaccessibleplugin.h \
|
||||
accessible/qplatformaccessibility_qpa.h
|
||||
|
||||
SOURCES += accessible/qaccessible.cpp \
|
||||
accessible/qaccessible2.cpp \
|
||||
accessible/qaccessibleobject.cpp \
|
||||
accessible/qaccessibleplugin.cpp \
|
||||
accessible/qplatformaccessibility_qpa.cpp
|
||||
|
||||
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
|
||||
# }
|
||||
}
|
@ -44,14 +44,16 @@
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#include "qaccessibleplugin.h"
|
||||
#include "qaccessiblewidget.h"
|
||||
#include "qapplication.h"
|
||||
#include "qhash.h"
|
||||
#include "qmetaobject.h"
|
||||
#include "qmutex.h"
|
||||
#include <private/qfactoryloader_p.h>
|
||||
#include "qaccessibleobject.h"
|
||||
#include "qaccessiblebridge.h"
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include "qplatformaccessibility_qpa.h"
|
||||
|
||||
#include "qwidget.h"
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QMutex>
|
||||
#include <private/qfactoryloader_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -438,16 +440,10 @@ QT_BEGIN_NAMESPACE
|
||||
Destroys the object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QAccessible::initialize()
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QAccessible::cleanup()
|
||||
\internal
|
||||
*/
|
||||
|
||||
|
||||
/* accessible widgets plugin discovery stuff */
|
||||
#ifndef QT_NO_LIBRARY
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
|
||||
(QAccessibleFactoryInterface_iid, QLatin1String("/accessible")))
|
||||
@ -460,6 +456,22 @@ QAccessible::RootObjectHandler QAccessible::rootObjectHandler = 0;
|
||||
|
||||
static bool accessibility_active = false;
|
||||
static bool cleanupAdded = false;
|
||||
|
||||
static QPlatformAccessibility *platformAccessibility()
|
||||
{
|
||||
QPlatformIntegration *pfIntegration = QGuiApplicationPrivate::platformIntegration();
|
||||
return pfIntegration ? pfIntegration->accessibility() : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
void QAccessible::cleanup()
|
||||
{
|
||||
if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
|
||||
pfAccessibility->cleanup();
|
||||
}
|
||||
|
||||
static void qAccessibleCleanup()
|
||||
{
|
||||
qAccessibleFactories()->clear();
|
||||
@ -507,6 +519,7 @@ static void qAccessibleCleanup()
|
||||
The function is called by setRootObject().
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
Installs the InterfaceFactory \a factory. The last factory added
|
||||
is the first one used by queryAccessibleInterface().
|
||||
@ -585,7 +598,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
|
||||
return 0;
|
||||
|
||||
QEvent e(QEvent::AccessibilityPrepare);
|
||||
QApplication::sendEvent(object, &e);
|
||||
|
||||
QCoreApplication::sendEvent(object, &e);
|
||||
|
||||
const QMetaObject *mo = object->metaObject();
|
||||
while (mo) {
|
||||
@ -607,13 +621,11 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
|
||||
mo = mo->superClass();
|
||||
}
|
||||
|
||||
QWidget *widget = qobject_cast<QWidget*>(object);
|
||||
if (widget)
|
||||
return new QAccessibleWidget(widget);
|
||||
else if (object == qApp)
|
||||
return new QAccessibleApplication();
|
||||
|
||||
return 0;
|
||||
if (!iface) {
|
||||
if (object == qApp)
|
||||
iface = new QAccessibleApplication;
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -628,9 +640,9 @@ bool QAccessible::isActive()
|
||||
return accessibility_active;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QAccessible::setRootObject(QObject *object)
|
||||
|
||||
|
||||
/*!
|
||||
Sets the root accessible object of this application to \a object.
|
||||
All other accessible objects in the application can be reached by the
|
||||
client using object navigation.
|
||||
@ -644,10 +656,18 @@ bool QAccessible::isActive()
|
||||
|
||||
\sa queryAccessibleInterface()
|
||||
*/
|
||||
void QAccessible::setRootObject(QObject *o)
|
||||
{
|
||||
if (rootObjectHandler) {
|
||||
rootObjectHandler(o);
|
||||
return;
|
||||
}
|
||||
|
||||
if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
|
||||
pfAccessibility->setRootObject(o);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QAccessible::updateAccessibility(QObject *object, int child, Event reason)
|
||||
|
||||
Notifies accessibility clients about a change in \a object's
|
||||
accessibility information.
|
||||
|
||||
@ -665,6 +685,21 @@ bool QAccessible::isActive()
|
||||
the parameters of the call is expensive you can test isActive() to
|
||||
avoid unnecessary computations.
|
||||
*/
|
||||
void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
|
||||
{
|
||||
Q_ASSERT(o);
|
||||
|
||||
if (updateHandler) {
|
||||
updateHandler(o, who, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isActive())
|
||||
return;
|
||||
|
||||
if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
|
||||
pfAccessibility->notifyAccessibilityUpdate(o, who, reason);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@ -1161,6 +1196,24 @@ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleInterfa
|
||||
|
||||
\sa value()
|
||||
*/
|
||||
/*!
|
||||
Returns the window associated with the underlying object.
|
||||
For instance, QAccessibleWidget reimplements this and returns
|
||||
the windowHandle() of the QWidget.
|
||||
|
||||
The default implementation returns the window() of the parent interface.
|
||||
|
||||
It is used on some platforms to be able to notify the AT client about
|
||||
state changes.
|
||||
\preliminary
|
||||
*/
|
||||
QWindow *QAccessibleInterface::window() const
|
||||
{
|
||||
QAccessibleInterface *par = parent();
|
||||
QWindow *w = par ? par->window() : 0;
|
||||
delete par;
|
||||
return w;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.2
|
@ -51,6 +51,8 @@
|
||||
#include <QtGui/qcolor.h>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
class QWindow;
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -61,7 +63,7 @@ QT_MODULE(Gui)
|
||||
|
||||
class QAccessibleInterface;
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessible
|
||||
class Q_GUI_EXPORT QAccessible
|
||||
{
|
||||
public:
|
||||
enum Event {
|
||||
@ -294,7 +296,7 @@ public:
|
||||
Increase = -3,
|
||||
Decrease = -4,
|
||||
Accept = -5,
|
||||
Cancel = -6,
|
||||
Cancel = -6,
|
||||
Select = -7,
|
||||
ClearSelection = -8,
|
||||
RemoveSelection = -9,
|
||||
@ -325,7 +327,6 @@ public:
|
||||
static bool isActive();
|
||||
static void setRootObject(QObject*);
|
||||
|
||||
static void initialize();
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
@ -362,13 +363,14 @@ class QAccessibleActionInterface;
|
||||
class QAccessibleImageInterface;
|
||||
class QAccessibleTable2Interface;
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleInterface : public QAccessible
|
||||
class Q_GUI_EXPORT QAccessibleInterface : public QAccessible
|
||||
{
|
||||
public:
|
||||
virtual ~QAccessibleInterface() {}
|
||||
// check for valid pointers
|
||||
virtual bool isValid() const = 0;
|
||||
virtual QObject *object() const = 0;
|
||||
virtual QWindow *window() const;
|
||||
|
||||
// hierarchy
|
||||
virtual int childCount() const = 0;
|
||||
@ -440,7 +442,7 @@ private:
|
||||
QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleEvent : public QEvent
|
||||
class QAccessibleEvent : public QEvent
|
||||
{
|
||||
public:
|
||||
inline QAccessibleEvent(Type type, int child);
|
@ -40,7 +40,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qaccessible2.h"
|
||||
#include "qapplication.h"
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include "qclipboard.h"
|
||||
#include "qtextboundaryfinder.h"
|
||||
|
||||
@ -137,7 +137,7 @@ QT_BEGIN_NAMESPACE
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QString Q_WIDGETS_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
|
||||
QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
|
||||
int *startOffset, int *endOffset, const QString& text)
|
||||
{
|
||||
QTextBoundaryFinder::BoundaryType type;
|
||||
@ -175,7 +175,7 @@ QString Q_WIDGETS_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::B
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QString Q_WIDGETS_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
|
||||
QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
|
||||
int *startOffset, int *endOffset, const QString& text)
|
||||
{
|
||||
QTextBoundaryFinder::BoundaryType type;
|
||||
@ -210,7 +210,7 @@ QString Q_WIDGETS_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::Bo
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QString Q_WIDGETS_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
|
||||
QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
|
||||
int *startOffset, int *endOffset, const QString& text)
|
||||
{
|
||||
QTextBoundaryFinder::BoundaryType type;
|
||||
@ -264,7 +264,7 @@ void QAccessibleSimpleEditableTextInterface::copyText(int startOffset, int endOf
|
||||
Q_UNUSED(startOffset);
|
||||
Q_UNUSED(endOffset);
|
||||
#else
|
||||
QApplication::clipboard()->setText(textForRange(iface, startOffset, endOffset));
|
||||
QGuiApplication::clipboard()->setText(textForRange(iface, startOffset, endOffset));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ void QAccessibleSimpleEditableTextInterface::cutText(int startOffset, int endOff
|
||||
#else
|
||||
QString sub = textForRange(iface, startOffset, endOffset);
|
||||
deleteText(startOffset, endOffset);
|
||||
QApplication::clipboard()->setText(sub);
|
||||
QGuiApplication::clipboard()->setText(sub);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ void QAccessibleSimpleEditableTextInterface::pasteText(int offset)
|
||||
Q_UNUSED(offset);
|
||||
#else
|
||||
QString txt = iface->text(QAccessible::Value, 0);
|
||||
txt.insert(offset, QApplication::clipboard()->text());
|
||||
txt.insert(offset, QGuiApplication::clipboard()->text());
|
||||
iface->setText(QAccessible::Value, 0, txt);
|
||||
#endif
|
||||
}
|
@ -42,7 +42,7 @@
|
||||
#ifndef QACCESSIBLE2_H
|
||||
#define QACCESSIBLE2_H
|
||||
|
||||
#include <QtWidgets/qaccessible.h>
|
||||
#include "qaccessible.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
@ -90,7 +90,7 @@ namespace QAccessible2
|
||||
};
|
||||
}
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
virtual ~QAccessible2Interface() {}
|
||||
@ -129,7 +129,7 @@ inline QAccessible2Interface *qAccessibleTable2CastHelper() { return 0; }
|
||||
} \
|
||||
private:
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleTextInterface: public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleTextInterface: public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleTextCastHelper() { return this; }
|
||||
@ -157,7 +157,7 @@ public:
|
||||
virtual void scrollToSubstring(int startIndex, int endIndex) = 0;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleEditableTextInterface: public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleEditableTextInterface: public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return this; }
|
||||
@ -173,7 +173,7 @@ public:
|
||||
virtual void setAttributes(int startOffset, int endOffset, const QString &attributes) = 0;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleSimpleEditableTextInterface: public QAccessibleEditableTextInterface
|
||||
class Q_GUI_EXPORT QAccessibleSimpleEditableTextInterface: public QAccessibleEditableTextInterface
|
||||
{
|
||||
public:
|
||||
QAccessibleSimpleEditableTextInterface(QAccessibleInterface *accessibleInterface);
|
||||
@ -190,7 +190,7 @@ private:
|
||||
QAccessibleInterface *iface;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleValueInterface: public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleValueInterface: public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleValueCastHelper() { return this; }
|
||||
@ -203,7 +203,7 @@ public:
|
||||
virtual QVariant minimumValue() = 0;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleTableInterface: public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleTableInterface: public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleTableCastHelper() { return this; }
|
||||
@ -237,7 +237,7 @@ public:
|
||||
int *columnSpan, bool *isSelected) = 0;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface
|
||||
class Q_GUI_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface
|
||||
{
|
||||
public:
|
||||
// Returns the number of columns occupied by this cell accessible.
|
||||
@ -266,7 +266,7 @@ public:
|
||||
virtual bool isExpandable() const = 0;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleTable2Interface: public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleTable2Interface: public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleTable2CastHelper() { return this; }
|
||||
@ -326,7 +326,7 @@ friend class QAbstractItemView;
|
||||
friend class QAbstractItemViewPrivate;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleActionInterface : public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleActionInterface : public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleActionCastHelper() { return this; }
|
||||
@ -339,7 +339,7 @@ public:
|
||||
virtual QStringList keyBindings(int actionIndex) = 0;
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleImageInterface : public QAccessible2Interface
|
||||
class Q_GUI_EXPORT QAccessibleImageInterface : public QAccessible2Interface
|
||||
{
|
||||
public:
|
||||
inline QAccessible2Interface *qAccessibleImageCastHelper() { return this; }
|
@ -63,7 +63,7 @@ public:
|
||||
virtual void notifyAccessibilityUpdate(int, QAccessibleInterface*, int) = 0;
|
||||
};
|
||||
|
||||
struct Q_WIDGETS_EXPORT QAccessibleBridgeFactoryInterface : public QFactoryInterface
|
||||
struct Q_GUI_EXPORT QAccessibleBridgeFactoryInterface : public QFactoryInterface
|
||||
{
|
||||
virtual QAccessibleBridge *create(const QString& name) = 0;
|
||||
};
|
||||
@ -71,7 +71,7 @@ struct Q_WIDGETS_EXPORT QAccessibleBridgeFactoryInterface : public QFactoryInter
|
||||
#define QAccessibleBridgeFactoryInterface_iid "com.trolltech.Qt.QAccessibleBridgeFactoryInterface"
|
||||
Q_DECLARE_INTERFACE(QAccessibleBridgeFactoryInterface, QAccessibleBridgeFactoryInterface_iid)
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleBridgePlugin : public QObject, public QAccessibleBridgeFactoryInterface
|
||||
class Q_GUI_EXPORT QAccessibleBridgePlugin : public QObject, public QAccessibleBridgeFactoryInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QAccessibleBridgeFactoryInterface:QFactoryInterface)
|
@ -43,11 +43,11 @@
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#include "qapplication.h"
|
||||
#include "qwidget.h"
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QWindow>
|
||||
|
||||
#include "qpointer.h"
|
||||
#include "qmetaobject.h"
|
||||
#include "qvarlengtharray.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -208,15 +208,27 @@ QAccessibleApplication::QAccessibleApplication()
|
||||
{
|
||||
}
|
||||
|
||||
// all toplevel widgets except popups and the desktop
|
||||
static QWidgetList topLevelWidgets()
|
||||
QWindow *QAccessibleApplication::window() const
|
||||
{
|
||||
QWidgetList list;
|
||||
const QWidgetList tlw(QApplication::topLevelWidgets());
|
||||
// an application can have several windows, and AFAIK we don't need
|
||||
// to notify about changes on the application.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// all toplevel windows except popups and the desktop
|
||||
static QObjectList topLevelObjects()
|
||||
{
|
||||
QObjectList list;
|
||||
const QWindowList tlw(QGuiApplication::topLevelWindows());
|
||||
for (int i = 0; i < tlw.count(); ++i) {
|
||||
QWidget *w = tlw.at(i);
|
||||
if (!(w->windowType() == Qt::Popup) && !(w->windowType() == Qt::Desktop))
|
||||
list.append(w);
|
||||
QWindow *w = tlw.at(i);
|
||||
if (w->windowType() != Qt::Popup && w->windowType() != Qt::Desktop) {
|
||||
if (QAccessibleInterface *root = w->accessibleRoot()) {
|
||||
if (root->object())
|
||||
list.append(w->accessibleRoot()->object());
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
@ -225,17 +237,14 @@ static QWidgetList topLevelWidgets()
|
||||
/*! \reimp */
|
||||
int QAccessibleApplication::childCount() const
|
||||
{
|
||||
return topLevelWidgets().count();
|
||||
return topLevelObjects().count();
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
int QAccessibleApplication::indexOfChild(const QAccessibleInterface *child) const
|
||||
{
|
||||
if (!child->object()->isWidgetType())
|
||||
return -1;
|
||||
|
||||
const QWidgetList tlw(topLevelWidgets());
|
||||
int index = tlw.indexOf(static_cast<QWidget*>(child->object()));
|
||||
const QObjectList tlw(topLevelObjects());
|
||||
int index = tlw.indexOf(child->object());
|
||||
if (index != -1)
|
||||
++index;
|
||||
return index;
|
||||
@ -244,13 +253,14 @@ int QAccessibleApplication::indexOfChild(const QAccessibleInterface *child) cons
|
||||
/*! \reimp */
|
||||
int QAccessibleApplication::childAt(int x, int y) const
|
||||
{
|
||||
const QWidgetList tlw(topLevelWidgets());
|
||||
for (int i = 0; i < tlw.count(); ++i) {
|
||||
QWidget *w = tlw.at(i);
|
||||
if (w->frameGeometry().contains(x,y))
|
||||
for (int i = 0; i < childCount(); ++i) {
|
||||
QAccessibleInterface *childIface = child(i);
|
||||
QRect geom = childIface->rect();
|
||||
if (geom.contains(x,y))
|
||||
return i+1;
|
||||
delete childIface;
|
||||
}
|
||||
return -1;
|
||||
return rect().contains(x,y) ? 0 : -1;
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
@ -270,17 +280,6 @@ QAccessible::Relation QAccessibleApplication::relationTo(int child, const
|
||||
return Self;
|
||||
}
|
||||
|
||||
QWidgetList tlw(topLevelWidgets());
|
||||
if (tlw.contains(qobject_cast<QWidget*>(o)))
|
||||
return Ancestor;
|
||||
|
||||
for (int i = 0; i < tlw.count(); ++i) {
|
||||
QWidget *w = tlw.at(i);
|
||||
QObjectList cl = w->findChildren<QObject *>(QString());
|
||||
if (cl.contains(o))
|
||||
return Ancestor;
|
||||
}
|
||||
|
||||
return Unrelated;
|
||||
}
|
||||
|
||||
@ -292,9 +291,9 @@ QAccessibleInterface *QAccessibleApplication::parent() const
|
||||
QAccessibleInterface *QAccessibleApplication::child(int index) const
|
||||
{
|
||||
Q_ASSERT(index >= 0);
|
||||
const QWidgetList tlw(topLevelWidgets());
|
||||
if (index >= 0 && index < tlw.count())
|
||||
return QAccessible::queryAccessibleInterface(tlw.at(index));
|
||||
const QObjectList tlo(topLevelObjects());
|
||||
if (index >= 0 && index < tlo.count())
|
||||
return QAccessible::queryAccessibleInterface(tlo.at(index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -312,18 +311,12 @@ int QAccessibleApplication::navigate(RelationFlag relation, int entry,
|
||||
case Self:
|
||||
targetObject = object();
|
||||
break;
|
||||
case Child:
|
||||
if (entry > 0 && entry <= childCount()) {
|
||||
const QWidgetList tlw(topLevelWidgets());
|
||||
if (tlw.count() >= entry)
|
||||
targetObject = tlw.at(entry-1);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case FocusChild:
|
||||
targetObject = QApplication::activeWindow();
|
||||
targetObject = QGuiApplication::activeWindow();
|
||||
break;
|
||||
case Ancestor:
|
||||
*target = parent();
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -336,9 +329,9 @@ QString QAccessibleApplication::text(Text t, int) const
|
||||
{
|
||||
switch (t) {
|
||||
case Name:
|
||||
return QApplication::applicationName();
|
||||
return QGuiApplication::applicationName();
|
||||
case Description:
|
||||
return QApplication::applicationFilePath();
|
||||
return QGuiApplication::applicationFilePath();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -354,7 +347,7 @@ QAccessible::Role QAccessibleApplication::role(int) const
|
||||
/*! \reimp */
|
||||
QAccessible::State QAccessibleApplication::state(int) const
|
||||
{
|
||||
return QApplication::activeWindow() ? Focused : Normal;
|
||||
return QGuiApplication::activeWindow() ? Focused : Normal;
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
@ -366,16 +359,19 @@ int QAccessibleApplication::userActionCount(int) const
|
||||
/*! \reimp */
|
||||
bool QAccessibleApplication::doAction(int action, int child, const QVariantList ¶m)
|
||||
{
|
||||
//###Move to IA2 action interface at some point to get rid of the ambiguity.
|
||||
/* //### what is action == 0 and action == 1 ?????
|
||||
if (action == 0 || action == 1) {
|
||||
QWidget *w = 0;
|
||||
w = QApplication::activeWindow();
|
||||
QWindow *w = 0;
|
||||
w = QGuiApplication::activeWindow();
|
||||
if (!w)
|
||||
w = topLevelWidgets().at(0);
|
||||
w = topLevelWindows().at(0);
|
||||
if (!w)
|
||||
return false;
|
||||
w->activateWindow();
|
||||
w->requestActivateWindow();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return QAccessibleObject::doAction(action, child, param);
|
||||
}
|
||||
|
||||
@ -385,9 +381,9 @@ QString QAccessibleApplication::actionText(int action, Text text, int child) con
|
||||
QString str;
|
||||
if ((action == 0 || action == 1) && !child) switch (text) {
|
||||
case Name:
|
||||
return QApplication::tr("Activate");
|
||||
return QGuiApplication::tr("Activate");
|
||||
case Description:
|
||||
return QApplication::tr("Activates the program's main window");
|
||||
return QGuiApplication::tr("Activates the program's main window");
|
||||
default:
|
||||
break;
|
||||
}
|
@ -42,7 +42,7 @@
|
||||
#ifndef QACCESSIBLEOBJECT_H
|
||||
#define QACCESSIBLEOBJECT_H
|
||||
|
||||
#include <QtWidgets/qaccessible.h>
|
||||
#include "qaccessible.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
@ -55,7 +55,7 @@ QT_MODULE(Gui)
|
||||
class QAccessibleObjectPrivate;
|
||||
class QObject;
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleObject : public QAccessibleInterface
|
||||
class Q_GUI_EXPORT QAccessibleObject : public QAccessibleInterface
|
||||
{
|
||||
public:
|
||||
explicit QAccessibleObject(QObject *object);
|
||||
@ -64,13 +64,13 @@ public:
|
||||
QObject *object() const;
|
||||
|
||||
// properties
|
||||
QRect rect(int child) const;
|
||||
QRect rect(int child = 0) const;
|
||||
void setText(Text t, int child, const QString &text);
|
||||
|
||||
// actions
|
||||
int userActionCount(int child) const;
|
||||
bool doAction(int action, int child, const QVariantList ¶ms);
|
||||
QString actionText(int action, Text t, int child) const;
|
||||
int userActionCount(int child = 0) const;
|
||||
bool doAction(int action, int child = 0, const QVariantList ¶ms = QVariantList());
|
||||
QString actionText(int action, Text t, int child = 0) const;
|
||||
|
||||
protected:
|
||||
virtual ~QAccessibleObject();
|
||||
@ -80,11 +80,12 @@ private:
|
||||
Q_DISABLE_COPY(QAccessibleObject)
|
||||
};
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessibleApplication : public QAccessibleObject
|
||||
class Q_GUI_EXPORT QAccessibleApplication : public QAccessibleObject
|
||||
{
|
||||
public:
|
||||
QAccessibleApplication();
|
||||
|
||||
QWindow *window() const;
|
||||
// relations
|
||||
int childCount() const;
|
||||
int indexOfChild(const QAccessibleInterface*) const;
|
||||
@ -97,14 +98,14 @@ public:
|
||||
int navigate(RelationFlag, int, QAccessibleInterface **) const;
|
||||
|
||||
// properties and state
|
||||
QString text(Text t, int child) const;
|
||||
Role role(int child) const;
|
||||
State state(int child) const;
|
||||
QString text(Text t, int child = 0) const;
|
||||
Role role(int child = 0) const;
|
||||
State state(int child = 0) const;
|
||||
|
||||
// actions
|
||||
int userActionCount(int child) const;
|
||||
bool doAction(int action, int child, const QVariantList ¶ms);
|
||||
QString actionText(int action, Text t, int child) const;
|
||||
int userActionCount(int child = 0) const;
|
||||
bool doAction(int action, int child = 0, const QVariantList ¶ms = QVariantList());
|
||||
QString actionText(int action, Text t, int child = 0) const;
|
||||
};
|
||||
|
||||
#endif // QT_NO_ACCESSIBILITY
|
@ -39,10 +39,11 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qaccessibleplugin.h"
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#include "qaccessibleplugin.h"
|
||||
#include "qaccessible.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
@ -42,7 +42,7 @@
|
||||
#ifndef QACCESSIBLEPLUGIN_H
|
||||
#define QACCESSIBLEPLUGIN_H
|
||||
|
||||
#include <QtWidgets/qaccessible.h>
|
||||
#include "qaccessible.h"
|
||||
#include <QtCore/qfactoryinterface.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
@ -56,7 +56,7 @@ QT_MODULE(Gui)
|
||||
class QStringList;
|
||||
class QAccessibleInterface;
|
||||
|
||||
struct Q_WIDGETS_EXPORT QAccessibleFactoryInterface : public QAccessible, public QFactoryInterface
|
||||
struct Q_GUI_EXPORT QAccessibleFactoryInterface : public QAccessible, public QFactoryInterface
|
||||
{
|
||||
virtual QAccessibleInterface* create(const QString &key, QObject *object) = 0;
|
||||
};
|
||||
@ -66,7 +66,7 @@ Q_DECLARE_INTERFACE(QAccessibleFactoryInterface, QAccessibleFactoryInterface_iid
|
||||
|
||||
class QAccessiblePluginPrivate;
|
||||
|
||||
class Q_WIDGETS_EXPORT QAccessiblePlugin : public QObject, public QAccessibleFactoryInterface
|
||||
class Q_GUI_EXPORT QAccessiblePlugin : public QObject, public QAccessibleFactoryInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QAccessibleFactoryInterface:QFactoryInterface)
|
@ -38,64 +38,45 @@
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qaccessible.h"
|
||||
#include "qplatformaccessibility_qpa.h"
|
||||
#include <private/qfactoryloader_p.h>
|
||||
#include "qaccessibleplugin.h"
|
||||
#include "qaccessibleobject.h"
|
||||
#include "qaccessiblebridge.h"
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#include "qcoreapplication.h"
|
||||
#include "qmutex.h"
|
||||
#include "qvector.h"
|
||||
#include "private/qfactoryloader_p.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/* accessiblebridge plugin discovery stuff */
|
||||
#ifndef QT_NO_LIBRARY
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, bridgeloader,
|
||||
(QAccessibleBridgeFactoryInterface_iid, QLatin1String("/accessiblebridge")))
|
||||
#endif
|
||||
|
||||
Q_GLOBAL_STATIC(QVector<QAccessibleBridge *>, bridges)
|
||||
static bool isInit = false;
|
||||
|
||||
void QAccessible::initialize()
|
||||
/*!
|
||||
\class QPlatformAccessibility
|
||||
\brief The QPlatformAccessibility class is the base class for
|
||||
integrating accessibility backends
|
||||
|
||||
\preliminary
|
||||
\ingroup accessibility
|
||||
|
||||
\sa QAccessible
|
||||
*/
|
||||
QPlatformAccessibility::QPlatformAccessibility()
|
||||
{
|
||||
if (isInit)
|
||||
return;
|
||||
isInit = true;
|
||||
|
||||
if (qgetenv("QT_ACCESSIBILITY") != "1")
|
||||
return;
|
||||
#ifndef QT_NO_LIBRARY
|
||||
const QStringList l = loader()->keys();
|
||||
for (int i = 0; i < l.count(); ++i) {
|
||||
if (QAccessibleBridgeFactoryInterface *factory =
|
||||
qobject_cast<QAccessibleBridgeFactoryInterface*>(loader()->instance(l.at(i)))) {
|
||||
QAccessibleBridge * bridge = factory->create(l.at(i));
|
||||
if (bridge)
|
||||
bridges()->append(bridge);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void QAccessible::cleanup()
|
||||
QPlatformAccessibility::~QPlatformAccessibility()
|
||||
{
|
||||
qDeleteAll(*bridges());
|
||||
}
|
||||
|
||||
void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
|
||||
void QPlatformAccessibility::notifyAccessibilityUpdate(QObject *o,
|
||||
int who,
|
||||
QAccessible::Event reason)
|
||||
{
|
||||
Q_ASSERT(o);
|
||||
|
||||
if (updateHandler) {
|
||||
updateHandler(o, who, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
initialize();
|
||||
|
||||
if (!bridges() || bridges()->isEmpty())
|
||||
return;
|
||||
|
||||
@ -117,15 +98,11 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
|
||||
for (int i = 0; i < bridges()->count(); ++i)
|
||||
bridges()->at(i)->notifyAccessibilityUpdate(reason, iface, who);
|
||||
delete iface;
|
||||
|
||||
}
|
||||
|
||||
void QAccessible::setRootObject(QObject *o)
|
||||
void QPlatformAccessibility::setRootObject(QObject *o)
|
||||
{
|
||||
if (rootObjectHandler) {
|
||||
rootObjectHandler(o);
|
||||
return;
|
||||
}
|
||||
|
||||
initialize();
|
||||
if (bridges()->isEmpty())
|
||||
return;
|
||||
@ -139,7 +116,33 @@ void QAccessible::setRootObject(QObject *o)
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
void QPlatformAccessibility::initialize()
|
||||
{
|
||||
static bool isInit = false;
|
||||
if (isInit)
|
||||
return;
|
||||
isInit = true; // ### not atomic
|
||||
#ifdef Q_OS_UNIX
|
||||
if (qgetenv("QT_ACCESSIBILITY") != "1")
|
||||
return;
|
||||
#endif
|
||||
#ifndef QT_NO_LIBRARY
|
||||
const QStringList l = bridgeloader()->keys();
|
||||
for (int i = 0; i < l.count(); ++i) {
|
||||
if (QAccessibleBridgeFactoryInterface *factory =
|
||||
qobject_cast<QAccessibleBridgeFactoryInterface*>(bridgeloader()->instance(l.at(i)))) {
|
||||
QAccessibleBridge * bridge = factory->create(l.at(i));
|
||||
if (bridge) {
|
||||
bridges()->append(bridge);
|
||||
#
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // QT_NO_ACCESSIBILITY
|
||||
void QPlatformAccessibility::cleanup()
|
||||
{
|
||||
qDeleteAll(*bridges());
|
||||
}
|
||||
|
74
src/gui/accessible/qplatformaccessibility_qpa.h
Normal file
74
src/gui/accessible/qplatformaccessibility_qpa.h
Normal file
@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 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 QPLATFORMACCESSIBILITY_H
|
||||
#define QPLATFORMACCESSIBILITY_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#include "qaccessible.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(Gui)
|
||||
|
||||
class Q_GUI_EXPORT QPlatformAccessibility
|
||||
{
|
||||
public:
|
||||
QPlatformAccessibility();
|
||||
|
||||
virtual ~QPlatformAccessibility();
|
||||
virtual void notifyAccessibilityUpdate(QObject *o, int who, QAccessible::Event reason);
|
||||
virtual void setRootObject(QObject *o);
|
||||
virtual void initialize();
|
||||
virtual void cleanup();
|
||||
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QT_NO_ACCESSIBILITY
|
||||
|
||||
#endif // QPLATFORMACCESSIBILITY_H
|
@ -15,6 +15,7 @@ load(qt_module_config)
|
||||
|
||||
HEADERS += $$QT_SOURCE_TREE/src/gui/qtguiversion.h
|
||||
|
||||
include(accessible/accessible.pri)
|
||||
include(kernel/kernel.pri)
|
||||
include(image/image.pri)
|
||||
include(text/text.pri)
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include <QtGui/QPlatformFontDatabase>
|
||||
#include <QtGui/QPlatformClipboard>
|
||||
#include <QtGui/QPlatformAccessibility>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtGui/private/qpixmap_raster_p.h>
|
||||
#include <private/qdnd_p.h>
|
||||
@ -209,6 +210,16 @@ QPlatformInputContext *QPlatformIntegration::inputContext() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the platforms accessibility.
|
||||
|
||||
The default implementation returns 0, implying no accessibility support.
|
||||
*/
|
||||
QPlatformAccessibility *QPlatformIntegration::accessibility() const
|
||||
{
|
||||
return new QPlatformAccessibility;
|
||||
}
|
||||
|
||||
QVariant QPlatformIntegration::styleHint(StyleHint hint) const
|
||||
{
|
||||
switch (hint) {
|
||||
|
@ -67,6 +67,7 @@ class QMenu;
|
||||
class QMenuBar;
|
||||
class QPlatformMenu;
|
||||
class QPlatformMenuBar;
|
||||
class QPlatformAccessibility;
|
||||
|
||||
class Q_GUI_EXPORT QPlatformIntegration
|
||||
{
|
||||
@ -101,6 +102,7 @@ public:
|
||||
|
||||
virtual QPlatformMenu *createPlatformMenu(QMenu *menu = 0) const;
|
||||
virtual QPlatformMenuBar *createPlatformMenuBar(QMenuBar *menuBar = 0) const;
|
||||
virtual QPlatformAccessibility *accessibility() const;
|
||||
|
||||
// Access native handles. The window handle is already available from Wid;
|
||||
virtual QPlatformNativeInterface *nativeInterface() const;
|
||||
|
@ -559,6 +559,8 @@ void QWindow::setScreen(QScreen *newScreen)
|
||||
|
||||
/*!
|
||||
Returns the accessibility interface for the object that the window represents
|
||||
\preliminary
|
||||
\sa QAccessible
|
||||
*/
|
||||
QAccessibleInterface *QWindow::accessibleRoot() const
|
||||
{
|
||||
|
@ -45,7 +45,7 @@
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtWidgets/qaccessiblewidget.h>
|
||||
#include <QtWidgets/qabstractitemview.h>
|
||||
#include <QtWidgets/qaccessible2.h>
|
||||
#include <QtGui/qaccessible2.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -44,8 +44,8 @@
|
||||
|
||||
#include <QtWidgets/qabstractitemview.h>
|
||||
#include <QtWidgets/qheaderview.h>
|
||||
#include <QtWidgets/qaccessible.h>
|
||||
#include <QtWidgets/qaccessible2.h>
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QtGui/qaccessible2.h>
|
||||
#include <QtWidgets/qaccessiblewidget.h>
|
||||
|
||||
|
||||
|
@ -153,6 +153,7 @@ QStringList AccessibleFactory::keys() const
|
||||
#ifndef QT_NO_DOCKWIDGET
|
||||
list << QLatin1String("QDockWidget");
|
||||
#endif
|
||||
list << QLatin1String("QAccessibleWidget");
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -348,6 +349,8 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
|
||||
} else if (classname == QLatin1String("QDockWidget")) {
|
||||
iface = new QAccessibleDockWidget(widget);
|
||||
#endif
|
||||
} else {
|
||||
iface = new QAccessibleWidget(widget);
|
||||
}
|
||||
|
||||
return iface;
|
||||
|
@ -42,7 +42,7 @@
|
||||
#ifndef QACCESSIBLEWIDGETS_H
|
||||
#define QACCESSIBLEWIDGETS_H
|
||||
|
||||
#include <QtWidgets/qaccessible2.h>
|
||||
#include <QtGui/qaccessible2.h>
|
||||
#include <QtWidgets/qaccessiblewidget.h>
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
@ -43,7 +43,7 @@
|
||||
#define RANGECONTROLS_H
|
||||
|
||||
#include <QtWidgets/qaccessiblewidget.h>
|
||||
#include <QtWidgets/qaccessible2.h>
|
||||
#include <QtGui/qaccessible2.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
#define SIMPLEWIDGETS_H
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtWidgets/qaccessible2.h>
|
||||
#include <QtGui/qaccessible2.h>
|
||||
#include <QtWidgets/qaccessiblewidget.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -88,6 +88,7 @@ enum WindowsEventType // Simplify event types
|
||||
ClipboardEvent = ClipboardEventFlag + 1,
|
||||
ActivateApplicationEvent = ApplicationEventFlag + 1,
|
||||
DeactivateApplicationEvent = ApplicationEventFlag + 2,
|
||||
AccessibleObjectFromWindowRequest = ApplicationEventFlag + 3,
|
||||
InputMethodStartCompositionEvent = InputMethodEventFlag + 1,
|
||||
InputMethodCompositionEvent = InputMethodEventFlag + 2,
|
||||
InputMethodEndCompositionEvent = InputMethodEventFlag + 3,
|
||||
@ -166,6 +167,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case WM_GETOBJECT:
|
||||
return QtWindows::AccessibleObjectFromWindowRequest;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
@ -38,20 +38,32 @@
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qaccessible.h"
|
||||
|
||||
#include <QtCore/QtConfig>
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
#include "qapplication.h"
|
||||
|
||||
#include "qwindowsaccessibility.h"
|
||||
#include "qwindowscontext.h"
|
||||
|
||||
#include <private/qsystemlibrary_p.h>
|
||||
#include "qmessagebox.h" // ### dependency
|
||||
#include "qt_windows.h"
|
||||
#include "qwidget.h"
|
||||
#include "qsettings.h"
|
||||
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qsettings.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtWidgets/qapplication.h>
|
||||
#include <QtWidgets/qmessagebox.h>
|
||||
#include <QtWidgets/qgraphicsitem.h>
|
||||
#include <QtWidgets/qgraphicsscene.h>
|
||||
#include <QtWidgets/qgraphicsview.h>
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QtGui/qplatformnativeinterface_qpa.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include "qt_windows.h"
|
||||
|
||||
//#include <uiautomationcoreapi.h>
|
||||
#ifndef UiaRootObjectId
|
||||
#define UiaRootObjectId -25
|
||||
#endif
|
||||
|
||||
#include <winuser.h>
|
||||
#if !defined(WINABLEAPI)
|
||||
@ -255,9 +267,9 @@ static const char *eventString(QAccessible::Event ev)
|
||||
|
||||
void showDebug(const char* funcName, const QAccessibleInterface *iface)
|
||||
{
|
||||
qDebug() << "Role:" << roleString(iface->role(0))
|
||||
<< "Name:" << iface->text(QAccessible::Name, 0)
|
||||
<< "State:" << QString::number(int(iface->state(0)), 16)
|
||||
qDebug() << "Role:" << roleString(iface->role(0))
|
||||
<< "Name:" << iface->text(QAccessible::Name, 0)
|
||||
<< "State:" << QString::number(int(iface->state(0)), 16)
|
||||
<< QLatin1String(funcName);
|
||||
}
|
||||
#else
|
||||
@ -269,229 +281,6 @@ typedef QMap<int, QPair<QObject*,int> > NotifyMap;
|
||||
Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
|
||||
static int eventNum = 0;
|
||||
|
||||
|
||||
void QAccessible::initialize()
|
||||
{
|
||||
|
||||
}
|
||||
void QAccessible::cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
|
||||
{
|
||||
Q_ASSERT(o);
|
||||
|
||||
if (updateHandler) {
|
||||
updateHandler(o, who, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
QString soundName;
|
||||
switch (reason) {
|
||||
case PopupMenuStart:
|
||||
soundName = QLatin1String("MenuPopup");
|
||||
break;
|
||||
|
||||
case MenuCommand:
|
||||
soundName = QLatin1String("MenuCommand");
|
||||
break;
|
||||
|
||||
case Alert:
|
||||
{
|
||||
#ifndef QT_NO_MESSAGEBOX
|
||||
QMessageBox *mb = qobject_cast<QMessageBox*>(o);
|
||||
if (mb) {
|
||||
switch (mb->icon()) {
|
||||
case QMessageBox::Warning:
|
||||
soundName = QLatin1String("SystemExclamation");
|
||||
break;
|
||||
case QMessageBox::Critical:
|
||||
soundName = QLatin1String("SystemHand");
|
||||
break;
|
||||
case QMessageBox::Information:
|
||||
soundName = QLatin1String("SystemAsterisk");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
#endif // QT_NO_MESSAGEBOX
|
||||
{
|
||||
soundName = QLatin1String("SystemAsterisk");
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (soundName.size()) {
|
||||
#ifndef QT_NO_SETTINGS
|
||||
QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
|
||||
QSettings::NativeFormat);
|
||||
QString file = settings.value(QLatin1String(".Current/.")).toString();
|
||||
#else
|
||||
QString file;
|
||||
#endif
|
||||
if (!file.isEmpty()) {
|
||||
PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isActive())
|
||||
return;
|
||||
|
||||
typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG);
|
||||
|
||||
#if defined(Q_WS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0
|
||||
// There is no user32.lib nor NotifyWinEvent for CE
|
||||
return;
|
||||
#else
|
||||
static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
|
||||
static bool resolvedNWE = false;
|
||||
if (!resolvedNWE) {
|
||||
resolvedNWE = true;
|
||||
ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
|
||||
}
|
||||
if (!ptrNotifyWinEvent)
|
||||
return;
|
||||
|
||||
// An event has to be associated with a window,
|
||||
// so find the first parent that is a widget.
|
||||
QWidget *w = 0;
|
||||
QObject *p = o;
|
||||
do {
|
||||
if (p->isWidgetType()) {
|
||||
w = static_cast<QWidget*>(p);
|
||||
if (w->internalWinId())
|
||||
break;
|
||||
}
|
||||
if (QGraphicsObject *gfxObj = qobject_cast<QGraphicsObject*>(p)) {
|
||||
QGraphicsItem *parentItem = gfxObj->parentItem();
|
||||
if (parentItem) {
|
||||
p = parentItem->toGraphicsObject();
|
||||
} else {
|
||||
QGraphicsView *view = 0;
|
||||
if (QGraphicsScene *scene = gfxObj->scene()) {
|
||||
QWidget *fw = QApplication::focusWidget();
|
||||
const QList<QGraphicsView*> views = scene->views();
|
||||
for (int i = 0 ; i < views.count() && view != fw; ++i) {
|
||||
view = views.at(i);
|
||||
}
|
||||
}
|
||||
p = view;
|
||||
}
|
||||
} else {
|
||||
p = p->parent();
|
||||
}
|
||||
|
||||
} while (p);
|
||||
|
||||
//qDebug() << "updateAccessibility(), hwnd:" << w << ", object:" << o << "," << eventString(reason);
|
||||
if (!w) {
|
||||
if (reason != QAccessible::ContextHelpStart &&
|
||||
reason != QAccessible::ContextHelpEnd)
|
||||
w = QApplication::focusWidget();
|
||||
if (!w) {
|
||||
w = QApplication::activeWindow();
|
||||
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
// ### Fixme
|
||||
// if (!w) {
|
||||
// w = qApp->mainWidget();
|
||||
// if (!w)
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
WId wid = w->internalWinId();
|
||||
if (reason != MenuCommand) { // MenuCommand is faked
|
||||
if (w != o) {
|
||||
// See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
|
||||
eventNum %= 50; //[0..49]
|
||||
int eventId = - eventNum - 1;
|
||||
|
||||
qAccessibleRecentSentEvents()->insert(eventId, qMakePair(o,who));
|
||||
ptrNotifyWinEvent(reason, wid, OBJID_CLIENT, eventId );
|
||||
|
||||
++eventNum;
|
||||
} else {
|
||||
ptrNotifyWinEvent(reason, wid, OBJID_CLIENT, who);
|
||||
}
|
||||
}
|
||||
#endif // Q_WS_WINCE
|
||||
}
|
||||
|
||||
/* == SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE ==
|
||||
|
||||
If the user requested to send the event to a widget with no window,
|
||||
we need to send an event to an object with no hwnd.
|
||||
The way we do that is to send it to the *first* ancestor widget
|
||||
with a window.
|
||||
Then we'll need a way of identifying the child:
|
||||
We'll just keep a list of the most recent events that we have sent,
|
||||
where each entry in the list is identified by a negative value
|
||||
between [-50,-1]. This negative value we will pass on to
|
||||
NotifyWinEvent() as the child id. When the negative value have
|
||||
reached -50, it will wrap around to -1. This seems to be enough
|
||||
|
||||
Now, when the client receives that event, he will first call
|
||||
AccessibleObjectFromEvent() where dwChildID is the special
|
||||
negative value. AccessibleObjectFromEvent does two steps:
|
||||
1. It will first sent a WM_GETOBJECT to the server, asking
|
||||
for the IAccessible interface for the HWND.
|
||||
2. With the IAccessible interface it got hold of it will call
|
||||
acc_getChild where the child id argument is the special
|
||||
negative identifier. In our reimplementation of get_accChild
|
||||
we check for this if the child id is negative. If it is, then
|
||||
we'll look up in our table for the entry that is associated
|
||||
with that value.
|
||||
The entry will then contain a pointer to the QObject /QWidget
|
||||
that we can use to call queryAccessibleInterface() on.
|
||||
|
||||
|
||||
The following figure shows how the interaction between server and
|
||||
client is in the case when the server is sending an event.
|
||||
|
||||
SERVER (Qt) | CLIENT |
|
||||
--------------------------------------------+---------------------------------------+
|
||||
|
|
||||
acc->updateAccessibility(obj, childIndex) |
|
||||
|
|
||||
recentEvents()->insert(- 1 - eventNum, |
|
||||
qMakePair(obj, childIndex) |
|
||||
NotifyWinEvent(hwnd, childId) => |
|
||||
| AccessibleObjectFromEvent(event, hwnd, OBJID_CLIENT, childId )
|
||||
| will do:
|
||||
<=== 1. send WM_GETOBJECT(hwnd, OBJID_CLIENT)
|
||||
widget ~= hwnd
|
||||
iface = queryAccessibleInteface(widget)
|
||||
(create IAccessible interface wrapper for
|
||||
iface)
|
||||
return iface ===> IAccessible* iface; (for hwnd)
|
||||
|
|
||||
<=== call iface->get_accChild(childId)
|
||||
get_accChild() { |
|
||||
if (varChildID.lVal < 0) {
|
||||
QPair ref = recentEvents().value(varChildID.lVal);
|
||||
[...]
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void QAccessible::setRootObject(QObject *o)
|
||||
{
|
||||
if (rootObjectHandler) {
|
||||
rootObjectHandler(o);
|
||||
}
|
||||
}
|
||||
|
||||
class QWindowsEnumerate : public IEnumVARIANT
|
||||
{
|
||||
public:
|
||||
@ -674,14 +463,6 @@ static inline BSTR QStringToBSTR(const QString &str)
|
||||
|
||||
/*
|
||||
*/
|
||||
IAccessible *qt_createWindowsAccessible(QAccessibleInterface *access)
|
||||
{
|
||||
QWindowsAccessible *acc = new QWindowsAccessible(access);
|
||||
IAccessible *iface;
|
||||
acc->QueryInterface(IID_IAccessible, (void**)&iface);
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
/*
|
||||
IUnknown
|
||||
@ -742,45 +523,45 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetIDsOfNames(const _GUID &, wchar
|
||||
// PROPERTIES: Hierarchical
|
||||
if (_bstr_t(rgszNames[0]) == _bstr_t(L"accParent"))
|
||||
rgdispid[0] = DISPID_ACC_PARENT;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accChildCount"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accChildCount"))
|
||||
rgdispid[0] = DISPID_ACC_CHILDCOUNT;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accChild"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accChild"))
|
||||
rgdispid[0] = DISPID_ACC_CHILD;
|
||||
|
||||
// PROPERTIES: Descriptional
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accName("))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accName("))
|
||||
rgdispid[0] = DISPID_ACC_NAME;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accValue"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accValue"))
|
||||
rgdispid[0] = DISPID_ACC_VALUE;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDescription"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accDescription"))
|
||||
rgdispid[0] = DISPID_ACC_DESCRIPTION;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accRole"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accRole"))
|
||||
rgdispid[0] = DISPID_ACC_ROLE;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accState"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accState"))
|
||||
rgdispid[0] = DISPID_ACC_STATE;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHelp"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accHelp"))
|
||||
rgdispid[0] = DISPID_ACC_HELP;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHelpTopic"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accHelpTopic"))
|
||||
rgdispid[0] = DISPID_ACC_HELPTOPIC;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accKeyboardShortcut"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accKeyboardShortcut"))
|
||||
rgdispid[0] = DISPID_ACC_KEYBOARDSHORTCUT;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accFocus"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accFocus"))
|
||||
rgdispid[0] = DISPID_ACC_FOCUS;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accSelection"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accSelection"))
|
||||
rgdispid[0] = DISPID_ACC_SELECTION;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDefaultAction"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accDefaultAction"))
|
||||
rgdispid[0] = DISPID_ACC_DEFAULTACTION;
|
||||
|
||||
// METHODS
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accSelect"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accSelect"))
|
||||
rgdispid[0] = DISPID_ACC_SELECT;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accLocation"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accLocation"))
|
||||
rgdispid[0] = DISPID_ACC_LOCATION;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accNavigate"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accNavigate"))
|
||||
rgdispid[0] = DISPID_ACC_NAVIGATE;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHitTest"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accHitTest"))
|
||||
rgdispid[0] = DISPID_ACC_HITTEST;
|
||||
else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDoDefaultAction"))
|
||||
else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accDoDefaultAction"))
|
||||
rgdispid[0] = DISPID_ACC_DODEFAULTACTION;
|
||||
else
|
||||
return DISP_E_UNKNOWNINTERFACE;
|
||||
@ -798,7 +579,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::Invoke(long dispIdMember, const _G
|
||||
{
|
||||
HRESULT hr = DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
switch(dispIdMember)
|
||||
switch (dispIdMember)
|
||||
{
|
||||
case DISPID_ACC_PARENT:
|
||||
if (wFlags == DISPATCH_PROPERTYGET) {
|
||||
@ -1021,7 +802,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT v
|
||||
|
||||
QAccessibleInterface *acc = 0;
|
||||
int control = -1;
|
||||
switch(navDir) {
|
||||
switch (navDir) {
|
||||
case NAVDIR_FIRSTCHILD:
|
||||
control = accessible->navigate(Child, 1, &acc);
|
||||
break;
|
||||
@ -1422,11 +1203,27 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetWindow(HWND *phwnd)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
QObject *o = accessible->object();
|
||||
if (!o || !o->isWidgetType())
|
||||
QWindow *window = qobject_cast<QWindow*>(o);
|
||||
if (!window)
|
||||
window = QGuiApplication::topLevelWindows().first();
|
||||
|
||||
|
||||
Q_ASSERT(window);
|
||||
if (!o || !window)
|
||||
return E_FAIL;
|
||||
|
||||
|
||||
#ifdef Q_WS_QPA
|
||||
//QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
|
||||
//Q_ASSERT(platform);
|
||||
//*phwnd = (HWND)platform->nativeResourceForWindow("handle", window);
|
||||
|
||||
|
||||
return S_OK;
|
||||
#else
|
||||
*phwnd = static_cast<QWidget*>(o)->effectiveWinId();
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsAccessible::ContextSensitiveHelp(BOOL)
|
||||
@ -1434,6 +1231,176 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::ContextSensitiveHelp(BOOL)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
QWindowsAccessibility::QWindowsAccessibility()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void QWindowsAccessibility::notifyAccessibilityUpdate(QObject *o, int who, QAccessible::Event reason)
|
||||
{
|
||||
QString soundName;
|
||||
switch (reason) {
|
||||
case QAccessible::PopupMenuStart:
|
||||
soundName = QLatin1String("MenuPopup");
|
||||
break;
|
||||
|
||||
case QAccessible::MenuCommand:
|
||||
soundName = QLatin1String("MenuCommand");
|
||||
break;
|
||||
|
||||
case QAccessible::Alert:
|
||||
{
|
||||
/* ### FIXME
|
||||
#ifndef QT_NO_MESSAGEBOX
|
||||
QMessageBox *mb = qobject_cast<QMessageBox*>(o);
|
||||
if (mb) {
|
||||
switch (mb->icon()) {
|
||||
case QMessageBox::Warning:
|
||||
soundName = QLatin1String("SystemExclamation");
|
||||
break;
|
||||
case QMessageBox::Critical:
|
||||
soundName = QLatin1String("SystemHand");
|
||||
break;
|
||||
case QMessageBox::Information:
|
||||
soundName = QLatin1String("SystemAsterisk");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
#endif // QT_NO_MESSAGEBOX
|
||||
*/
|
||||
{
|
||||
soundName = QLatin1String("SystemAsterisk");
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!soundName.isEmpty()) {
|
||||
#ifndef QT_NO_SETTINGS
|
||||
QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
|
||||
QSettings::NativeFormat);
|
||||
QString file = settings.value(QLatin1String(".Current/.")).toString();
|
||||
#else
|
||||
QString file;
|
||||
#endif
|
||||
if (!file.isEmpty()) {
|
||||
PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG);
|
||||
|
||||
#if defined(Q_WS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0
|
||||
// There is no user32.lib nor NotifyWinEvent for CE
|
||||
return;
|
||||
#else
|
||||
static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
|
||||
static bool resolvedNWE = false;
|
||||
if (!resolvedNWE) {
|
||||
resolvedNWE = true;
|
||||
ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
|
||||
}
|
||||
if (!ptrNotifyWinEvent)
|
||||
return;
|
||||
|
||||
// An event has to be associated with a window,
|
||||
// so find the first parent that is a widget and that has a WId
|
||||
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(o);
|
||||
QWindow *window = iface->window();
|
||||
|
||||
if (!window) {
|
||||
window = QGuiApplication::activeWindow();
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
|
||||
QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
|
||||
HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window);
|
||||
|
||||
if (reason != QAccessible::MenuCommand) { // MenuCommand is faked
|
||||
// See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
|
||||
eventNum %= 50; //[0..49]
|
||||
int eventId = - eventNum - 1;
|
||||
|
||||
qAccessibleRecentSentEvents()->insert(eventId, qMakePair(o, who));
|
||||
ptrNotifyWinEvent(reason, hWnd, OBJID_CLIENT, eventId );
|
||||
|
||||
++eventNum;
|
||||
}
|
||||
#endif // Q_WS_WINCE
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void QWindowsAccessibility::setRootObject(QObject *o)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QWindowsAccessibility::initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QWindowsAccessibility::cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
|
||||
{
|
||||
if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) {
|
||||
/* For UI Automation
|
||||
*/
|
||||
} else if ((DWORD)lParam == OBJID_CLIENT) {
|
||||
#if 1
|
||||
// Ignoring all requests while starting up
|
||||
// ### Maybe QPA takes care of this???
|
||||
if (QApplication::startingUp() || QApplication::closingDown())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
|
||||
static PtrLresultFromObject ptrLresultFromObject = 0;
|
||||
static bool oleaccChecked = false;
|
||||
|
||||
if (!oleaccChecked) {
|
||||
oleaccChecked = true;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ptrLresultFromObject) {
|
||||
QWindow *window = QWindowsContext::instance()->findWindow(hwnd);
|
||||
if (window) {
|
||||
QAccessibleInterface *acc = window->accessibleRoot();
|
||||
if (acc) {
|
||||
QWindowsAccessible *winacc = new QWindowsAccessible(acc);
|
||||
IAccessible *iface;
|
||||
HRESULT hr = winacc->QueryInterface(IID_IAccessible, (void**)&iface);
|
||||
if (SUCCEEDED(hr)) {
|
||||
*lResult = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2
|
||||
if (*lResult) {
|
||||
iface->Release(); // the client will release the object again, and then it will destroy itself
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_ACCESSIBILITY
|
||||
#endif //QT_NO_ACCESSIBILITY
|
61
src/plugins/platforms/windows/qwindowsaccessibility.h
Normal file
61
src/plugins/platforms/windows/qwindowsaccessibility.h
Normal file
@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QWINDOWSACCESSIBILITY_H
|
||||
#define QWINDOWSACCESSIBILITY_H
|
||||
|
||||
#include <QtGui/QPlatformAccessibility>
|
||||
#include <OleAcc.h>
|
||||
|
||||
class QWindowsAccessibility : public QPlatformAccessibility
|
||||
{
|
||||
public:
|
||||
QWindowsAccessibility();
|
||||
static bool handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
|
||||
virtual void notifyAccessibilityUpdate(QObject *o, int who, QAccessible::Event reason);
|
||||
/*
|
||||
virtual void setRootObject(QObject *o);
|
||||
virtual void initialize();
|
||||
virtual void cleanup();
|
||||
*/
|
||||
};
|
||||
|
||||
#endif // QWINDOWSACCESSIBILITY_H
|
@ -47,6 +47,7 @@
|
||||
#include "qtwindowsglobal.h"
|
||||
#include "qwindowsmime.h"
|
||||
#include "qwindowsinputcontext.h"
|
||||
#include "qwindowsaccessibility.h"
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
@ -623,6 +624,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
|
||||
|
||||
case QtWindows::UnknownEvent:
|
||||
return false;
|
||||
case QtWindows::AccessibleObjectFromWindowRequest:
|
||||
return QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(hwnd, wParam, lParam, result);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "qwindowsclipboard.h"
|
||||
#include "qwindowsdrag.h"
|
||||
#include "qwindowsinputcontext.h"
|
||||
#include "qwindowsaccessibility.h"
|
||||
|
||||
#include <QtGui/QPlatformNativeInterface>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
@ -138,6 +139,7 @@ struct QWindowsIntegrationPrivate
|
||||
QWindowsGuiEventDispatcher *m_eventDispatcher;
|
||||
QOpenGLStaticContextPtr m_staticOpenGLContext;
|
||||
QWindowsInputContext m_inputContext;
|
||||
QWindowsAccessibility m_accessibility;
|
||||
};
|
||||
|
||||
QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(bool openGL)
|
||||
@ -258,6 +260,11 @@ QPlatformInputContext * QWindowsIntegration::inputContext() const
|
||||
return &d->m_inputContext;
|
||||
}
|
||||
|
||||
QPlatformAccessibility *QWindowsIntegration::accessibility() const
|
||||
{
|
||||
return &d->m_accessibility;
|
||||
}
|
||||
|
||||
QWindowsIntegration *QWindowsIntegration::instance()
|
||||
{
|
||||
return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
virtual QPlatformClipboard *clipboard() const;
|
||||
virtual QPlatformDrag *drag() const;
|
||||
virtual QPlatformInputContext *inputContext() const;
|
||||
virtual QPlatformAccessibility *accessibility() const;
|
||||
virtual QPlatformNativeInterface *nativeInterface() const;
|
||||
virtual QPlatformFontDatabase *fontDatabase() const;
|
||||
|
||||
|
@ -8,7 +8,7 @@ INCLUDEPATH += ../../../3rdparty/harfbuzz/src
|
||||
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
|
||||
|
||||
# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
|
||||
LIBS *= -lOpenGL32 -lGdi32 -lUser32 -lOle32 -lWinspool -lImm32
|
||||
LIBS *= -lOpenGL32 -lGdi32 -lUser32 -lOle32 -lWinspool -lImm32 -lWinmm
|
||||
win32-g++: LIBS *= -luuid
|
||||
|
||||
contains(QT_CONFIG, directwrite) {
|
||||
@ -39,7 +39,8 @@ SOURCES += \
|
||||
qwindowsdrag.cpp \
|
||||
qwindowscursor.cpp \
|
||||
pixmaputils.cpp \
|
||||
qwindowsinputcontext.cpp
|
||||
qwindowsinputcontext.cpp \
|
||||
qwindowsaccessibility.cpp
|
||||
|
||||
HEADERS += \
|
||||
qwindowsnativeimage.h \
|
||||
@ -64,7 +65,8 @@ HEADERS += \
|
||||
qwindowscursor.h \
|
||||
pixmaputils.h \
|
||||
array.h \
|
||||
qwindowsinputcontext.h
|
||||
qwindowsinputcontext.h \
|
||||
qwindowsaccessibility.h
|
||||
|
||||
target.path += $$[QT_INSTALL_PLUGINS]/platforms
|
||||
INSTALLS += target
|
||||
|
@ -53,8 +53,8 @@
|
||||
QVERIFY(QTestAccessibility::verifyEvent(object, child, (int)event))
|
||||
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtWidgets/qaccessible.h>
|
||||
#include <QtWidgets/qapplication.h>
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
@ -127,9 +127,9 @@ private:
|
||||
{
|
||||
// qDebug("rootObjectHandler called %p", object);
|
||||
if (object) {
|
||||
QApplication* app = qobject_cast<QApplication*>(object);
|
||||
QGuiApplication* app = qobject_cast<QGuiApplication*>(object);
|
||||
if ( !app )
|
||||
qWarning("%s: root Object is not a QApplication!", Q_FUNC_INFO);
|
||||
qWarning("%s: root Object is not a QGuiApplication!", Q_FUNC_INFO);
|
||||
} else {
|
||||
qWarning("%s: root Object called with 0 pointer", Q_FUNC_INFO);
|
||||
}
|
||||
|
@ -1,25 +1,6 @@
|
||||
# Qt accessibility module
|
||||
|
||||
contains(QT_CONFIG, accessibility) {
|
||||
HEADERS += accessible/qaccessible.h \
|
||||
accessible/qaccessible2.h \
|
||||
accessible/qaccessibleobject.h \
|
||||
accessible/qaccessiblewidget.h \
|
||||
accessible/qaccessibleplugin.h
|
||||
SOURCES += accessible/qaccessible.cpp \
|
||||
accessible/qaccessible2.cpp \
|
||||
accessible/qaccessibleobject.cpp \
|
||||
accessible/qaccessiblewidget.cpp \
|
||||
accessible/qaccessibleplugin.cpp
|
||||
|
||||
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
|
||||
}
|
||||
HEADERS += accessible/qaccessiblewidget.h
|
||||
SOURCES += accessible/qaccessiblewidget.cpp
|
||||
}
|
||||
|
@ -187,6 +187,11 @@ QAccessibleWidget::QAccessibleWidget(QWidget *w, Role role, const QString &name)
|
||||
d->asking = 0;
|
||||
}
|
||||
|
||||
QWindow *QAccessibleWidget::window() const
|
||||
{
|
||||
return widget()->windowHandle();
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys this object.
|
||||
*/
|
||||
|
@ -42,7 +42,7 @@
|
||||
#ifndef QACCESSIBLEWIDGET_H
|
||||
#define QACCESSIBLEWIDGET_H
|
||||
|
||||
#include <QtWidgets/qaccessibleobject.h>
|
||||
#include <QtGui/qaccessibleobject.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
@ -59,25 +59,26 @@ class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject
|
||||
public:
|
||||
explicit QAccessibleWidget(QWidget *o, Role r = Client, const QString& name = QString());
|
||||
|
||||
QWindow *window() const;
|
||||
int childCount() const;
|
||||
int indexOfChild(const QAccessibleInterface *child) const;
|
||||
Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
|
||||
|
||||
int childAt(int x, int y) const;
|
||||
QRect rect(int child) const;
|
||||
QRect rect(int child = 0) const;
|
||||
|
||||
QAccessibleInterface *parent() const;
|
||||
QAccessibleInterface *child(int index) const;
|
||||
int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
|
||||
|
||||
QString text(Text t, int child) const;
|
||||
Role role(int child) const;
|
||||
State state(int child) const;
|
||||
QString text(Text t, int child = 0) const;
|
||||
Role role(int child = 0) const;
|
||||
State state(int child = 0) const;
|
||||
|
||||
#ifndef QT_NO_ACTION
|
||||
int userActionCount(int child) const;
|
||||
QString actionText(int action, Text t, int child) const;
|
||||
bool doAction(int action, int child, const QVariantList ¶ms);
|
||||
int userActionCount(int child = 0) const;
|
||||
QString actionText(int action, Text t, int child = 0) const;
|
||||
bool doAction(int action, int child = 0, const QVariantList ¶ms = QVariantList());
|
||||
#endif
|
||||
|
||||
QVariant invokeMethod(Method method, int child, const QVariantList ¶ms);
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include <QtWidgets/qgridlayout.h>
|
||||
#include <QtWidgets/qdesktopwidget.h>
|
||||
#include <QtWidgets/qpushbutton.h>
|
||||
#include <QtWidgets/qaccessible.h>
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QtWidgets/qicon.h>
|
||||
#include <QtGui/qtextdocument.h>
|
||||
#include <QtWidgets/qapplication.h>
|
||||
|
@ -246,7 +246,7 @@
|
||||
#include <QtGui/qinputpanel.h>
|
||||
#include <QtWidgets/qgraphicseffect.h>
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
# include <QtWidgets/qaccessible.h>
|
||||
# include <QtGui/qaccessible.h>
|
||||
#endif
|
||||
#include <private/qapplication_p.h>
|
||||
#include <private/qobject_p.h>
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include "private/qwidget_p.h"
|
||||
#include "private/qapplication_p.h"
|
||||
#include <QtGui/qaccessible.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -59,6 +60,13 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
|
||||
{
|
||||
}
|
||||
|
||||
QAccessibleInterface *QWidgetWindow::accessibleRoot() const
|
||||
{
|
||||
if (m_widget)
|
||||
return QAccessible::queryAccessibleInterface(m_widget);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool QWidgetWindow::event(QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
QWidgetWindow(QWidget *widget);
|
||||
|
||||
QWidget *widget() const { return m_widget; }
|
||||
QAccessibleInterface *accessibleRoot() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *);
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "QtGui/qclipboard.h"
|
||||
#include "QtCore/qpoint.h"
|
||||
#include "QtWidgets/qcompleter.h"
|
||||
#include "QtWidgets/qaccessible.h"
|
||||
#include "QtCore/qthread.h"
|
||||
|
||||
#include "qplatformdefs.h"
|
||||
|
@ -353,7 +353,7 @@ class QtTestAccessibleWidgetIface: public QAccessibleWidget
|
||||
{
|
||||
public:
|
||||
QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidget(w) {}
|
||||
QString text(Text t, int control) const
|
||||
QString text(Text t, int control = 0) const
|
||||
{
|
||||
if (t == Help)
|
||||
return QString::fromLatin1("Help yourself");
|
||||
|
Loading…
Reference in New Issue
Block a user