summaryrefslogtreecommitdiffstats
path: root/src/gui/accessible/qaccessibleobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/accessible/qaccessibleobject.cpp')
-rw-r--r--src/gui/accessible/qaccessibleobject.cpp410
1 files changed, 410 insertions, 0 deletions
diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp
new file mode 100644
index 0000000..7df097b
--- /dev/null
+++ b/src/gui/accessible/qaccessibleobject.cpp
@@ -0,0 +1,410 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessibleobject.h"
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "qapplication.h"
+#include "qwidget.h"
+#include "qpointer.h"
+#include "qmetaobject.h"
+#include "qvarlengtharray.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAccessibleObjectPrivate
+{
+public:
+ QPointer<QObject> object;
+
+ QList<QByteArray> actionList() const;
+};
+
+QList<QByteArray> QAccessibleObjectPrivate::actionList() const
+{
+ QList<QByteArray> actionList;
+
+ if (!object)
+ return actionList;
+
+ const QMetaObject *mo = object->metaObject();
+ Q_ASSERT(mo);
+
+ QByteArray defaultAction = QMetaObject::normalizedSignature(
+ mo->classInfo(mo->indexOfClassInfo("DefaultSlot")).value());
+
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ const QMetaMethod member = mo->method(i);
+ if (member.methodType() != QMetaMethod::Slot && member.access() != QMetaMethod::Public)
+ continue;
+
+ if (!qstrcmp(member.tag(), "QACCESSIBLE_SLOT")) {
+ if (member.signature() == defaultAction)
+ actionList.prepend(defaultAction);
+ else
+ actionList << member.signature();
+ }
+ }
+
+ return actionList;
+}
+
+/*!
+ \class QAccessibleObject
+ \brief The QAccessibleObject class implements parts of the
+ QAccessibleInterface for QObjects.
+
+ \ingroup accessibility
+
+ This class is mainly provided for convenience. All subclasses of
+ the QAccessibleInterface that provide implementations of non-widget objects
+ should use this class as their base class.
+
+ \sa QAccessible, QAccessibleWidget
+*/
+
+/*!
+ Creates a QAccessibleObject for \a object.
+*/
+QAccessibleObject::QAccessibleObject(QObject *object)
+{
+ d = new QAccessibleObjectPrivate;
+ d->object = object;
+}
+
+/*!
+ Destroys the QAccessibleObject.
+
+ This only happens when a call to release() decrements the internal
+ reference counter to zero.
+*/
+QAccessibleObject::~QAccessibleObject()
+{
+ delete d;
+}
+
+/*!
+ \reimp
+*/
+QObject *QAccessibleObject::object() const
+{
+#ifndef QT_NO_DEBUG
+ if (!d->object)
+ qWarning("QAccessibleInterface is invalid. Crash pending...");
+#endif
+ return d->object;
+}
+
+/*!
+ \reimp
+*/
+bool QAccessibleObject::isValid() const
+{
+ return !d->object.isNull();
+}
+
+/*! \reimp */
+QRect QAccessibleObject::rect(int) const
+{
+ return QRect();
+}
+
+/*! \reimp */
+void QAccessibleObject::setText(Text, int, const QString &)
+{
+}
+
+/*! \reimp */
+int QAccessibleObject::userActionCount(int) const
+{
+ return 0;
+}
+
+/*! \reimp */
+bool QAccessibleObject::doAction(int, int, const QVariantList &)
+{
+ return false;
+}
+
+static const char * const action_text[][5] =
+{
+ // Name, Description, Value, Help, Accelerator
+ { "Press", "", "", "", "Space" },
+ { "SetFocus", "Passes focus to this widget", "", "", "" },
+ { "Increase", "", "", "", "" },
+ { "Decrease", "", "", "", "" },
+ { "Accept", "", "", "", "" },
+ { "Cancel", "", "", "", "" },
+ { "Select", "", "", "", "" },
+ { "ClearSelection", "", "", "", "" },
+ { "RemoveSelection", "", "", "", "" },
+ { "ExtendSelection", "", "", "", "" },
+ { "AddToSelection", "", "", "", "" }
+};
+
+/*! \reimp */
+QString QAccessibleObject::actionText(int action, Text t, int child) const
+{
+ if (child || action > FirstStandardAction || action < LastStandardAction || t > Accelerator)
+ return QString();
+
+ return QString::fromLatin1(action_text[-(action - FirstStandardAction)][t]);
+}
+
+
+/*!
+ \class QAccessibleApplication
+ \brief The QAccessibleApplication class implements the QAccessibleInterface for QApplication.
+
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Creates a QAccessibleApplication for the QApplication object referenced by qApp.
+*/
+QAccessibleApplication::QAccessibleApplication()
+: QAccessibleObject(qApp)
+{
+}
+
+// all toplevel widgets except popups and the desktop
+static QWidgetList topLevelWidgets()
+{
+ QWidgetList list;
+ const QWidgetList tlw(qApp->topLevelWidgets());
+ 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);
+ }
+
+ return list;
+}
+
+/*! \reimp */
+int QAccessibleApplication::childCount() const
+{
+ return topLevelWidgets().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()));
+ if (index != -1)
+ ++index;
+ return index;
+}
+
+/*! \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))
+ return i+1;
+ }
+ return -1;
+}
+
+/*! \reimp */
+QAccessible::Relation QAccessibleApplication::relationTo(int child, const
+ QAccessibleInterface *other, int otherChild) const
+{
+ QObject *o = other ? other->object() : 0;
+ if (!o)
+ return Unrelated;
+
+ if(o == object()) {
+ if (child && !otherChild)
+ return Child;
+ if (!child && otherChild)
+ return Ancestor;
+ if (!child && !otherChild)
+ 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 = qFindChildren<QObject *>(w, QString());
+ if (cl.contains(o))
+ return Ancestor;
+ }
+
+ return Unrelated;
+}
+
+/*! \reimp */
+int QAccessibleApplication::navigate(RelationFlag relation, int entry,
+ QAccessibleInterface **target) const
+{
+ if (!target)
+ return -1;
+
+ *target = 0;
+ QObject *targetObject = 0;
+
+ switch (relation) {
+ 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 = qApp->activeWindow();
+ break;
+ default:
+ break;
+ }
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ return *target ? 0 : -1;
+}
+
+/*! \reimp */
+QString QAccessibleApplication::text(Text t, int) const
+{
+ switch (t) {
+ case Name:
+ if (qApp->activeWindow())
+ return qApp->activeWindow()->windowTitle();
+ break;
+ case Description:
+ return qApp->applicationFilePath();
+ default:
+ break;
+ }
+ return QString();
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleApplication::role(int) const
+{
+ return Application;
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleApplication::state(int) const
+{
+ return qApp->activeWindow() ? Focused : Normal;
+}
+
+/*! \reimp */
+int QAccessibleApplication::userActionCount(int) const
+{
+ return 1;
+}
+
+/*! \reimp */
+bool QAccessibleApplication::doAction(int action, int child, const QVariantList &param)
+{
+ if (action == 0 || action == 1) {
+ QWidget *w = 0;
+ w = qApp->activeWindow();
+ if (!w)
+ w = topLevelWidgets().at(0);
+ if (!w)
+ return false;
+ w->activateWindow();
+ return true;
+ }
+ return QAccessibleObject::doAction(action, child, param);
+}
+
+/*! \reimp */
+QString QAccessibleApplication::actionText(int action, Text text, int child) const
+{
+ QString str;
+ if ((action == 0 || action == 1) && !child) switch (text) {
+ case Name:
+ return QApplication::tr("Activate");
+ case Description:
+ return QApplication::tr("Activates the program's main window");
+ default:
+ break;
+ }
+ return QAccessibleObject::actionText(action, text, child);
+}
+
+// ### Qt 5: remove me - binary compatibility hack
+QAccessibleObjectEx::QAccessibleObjectEx(QObject *object)
+{
+ d = new QAccessibleObjectPrivate;
+ d->object = object;
+}
+bool QAccessibleObjectEx::isValid() const
+{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::isValid(); }
+QObject *QAccessibleObjectEx::object() const
+{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::object(); }
+QRect QAccessibleObjectEx::rect(int child) const
+{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::rect(child); }
+void QAccessibleObjectEx::setText(Text t, int child, const QString &text)
+{ reinterpret_cast<QAccessibleObject *>(this)->QAccessibleObject::setText(t, child, text); }
+int QAccessibleObjectEx::userActionCount(int child) const
+{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::userActionCount(child); }
+bool QAccessibleObjectEx::doAction(int action, int child, const QVariantList &params)
+{ return reinterpret_cast<QAccessibleObject *>(this)->QAccessibleObject::doAction(action, child, params); }
+QString QAccessibleObjectEx::actionText(int action, Text t, int child) const
+{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::actionText(action, t, child); }
+QAccessibleObjectEx::~QAccessibleObjectEx()
+{ delete d; }
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ACCESSIBILITY