summaryrefslogtreecommitdiffstats
path: root/src/plugins/accessible
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/accessible')
-rw-r--r--src/plugins/accessible/accessible.pro6
-rw-r--r--src/plugins/accessible/qaccessiblebase.pri2
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.cpp2168
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.h293
-rw-r--r--src/plugins/accessible/widgets/main.cpp341
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.cpp678
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.h140
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp1667
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h318
-rw-r--r--src/plugins/accessible/widgets/rangecontrols.cpp991
-rw-r--r--src/plugins/accessible/widgets/rangecontrols.h235
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp888
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h193
-rw-r--r--src/plugins/accessible/widgets/widgets.pro20
14 files changed, 7940 insertions, 0 deletions
diff --git a/src/plugins/accessible/accessible.pro b/src/plugins/accessible/accessible.pro
new file mode 100644
index 0000000000..a7caf07106
--- /dev/null
+++ b/src/plugins/accessible/accessible.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+
+contains(QT_CONFIG, accessibility) {
+ SUBDIRS += widgets
+ contains(QT_CONFIG, qt3support):SUBDIRS += compat
+}
diff --git a/src/plugins/accessible/qaccessiblebase.pri b/src/plugins/accessible/qaccessiblebase.pri
new file mode 100644
index 0000000000..95c1fad13a
--- /dev/null
+++ b/src/plugins/accessible/qaccessiblebase.pri
@@ -0,0 +1,2 @@
+target.path += $$[QT_INSTALL_PLUGINS]/accessible
+INSTALLS += target
diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp
new file mode 100644
index 0000000000..e6384133c0
--- /dev/null
+++ b/src/plugins/accessible/widgets/complexwidgets.cpp
@@ -0,0 +1,2168 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "complexwidgets.h"
+
+#include <qapplication.h>
+#include <qabstractbutton.h>
+#include <qevent.h>
+#include <qheaderview.h>
+#include <qtabbar.h>
+#include <qcombobox.h>
+#include <qlistview.h>
+#include <qtableview.h>
+#include <qlineedit.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qtreeview.h>
+#include <private/qtabbar_p.h>
+#include <QAbstractScrollArea>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QDebug>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
+
+#ifndef QT_NO_ITEMVIEWS
+/*
+The MSDN article "Exposing Data Tables through Microsoft Active Accessibility" explains
+how data tables should be exposed. Url: http://msdn2.microsoft.com/en-us/library/ms971325.aspx
+Basically, the model is like this:
+
+ROLE_SYSTEM_TABLE
+ |- ROLE_SYSTEM_ROW
+ | |- ROLE_SYSTEM_ROWHEADER
+ | |- ROLE_SYSTEM_COLUMNHEADER
+ | |- ROLE_SYSTEM_COLUMNHEADER
+ | |- ROLE_SYSTEM_COLUMNHEADER
+ | '- ..
+ |- ROLE_SYSTEM_ROW
+ | |- ROLE_SYSTEM_ROWHEADER
+ | |- ROLE_SYSTEM_CELL
+ | |- ROLE_SYSTEM_CELL
+ | |- ROLE_SYSTEM_CELL
+ | '- ..
+ |- ROLE_SYSTEM_ROW
+ | |- ROLE_SYSTEM_ROWHEADER
+ | |- ROLE_SYSTEM_CELL
+ | |- ROLE_SYSTEM_CELL
+ | |- ROLE_SYSTEM_CELL
+ | '- ..
+ '- ..
+
+The headers of QTreeView is also represented like this.
+*/
+QAccessibleItemRow::QAccessibleItemRow(QAbstractItemView *aView, const QModelIndex &index, bool isHeader)
+ : row(index), view(aView), m_header(isHeader)
+{
+}
+
+QHeaderView *QAccessibleItemRow::horizontalHeader() const
+{
+ QHeaderView *header = 0;
+ if (m_header) {
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ header = tv->horizontalHeader();
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+ }
+ return header;
+}
+
+QHeaderView *QAccessibleItemRow::verticalHeader() const
+{
+ QHeaderView *header = 0;
+#ifndef QT_NO_TABLEVIEW
+ if (const QTableView *tv = qobject_cast<const QTableView*>(view))
+ header = tv->verticalHeader();
+#endif
+ return header;
+}
+
+int QAccessibleItemRow::logicalFromChild(QHeaderView *header, int child) const
+{
+ int logical = -1;
+ if (header->sectionsHidden()) {
+ int kid = 0;
+ for (int i = 0; i < header->count(); ++i) {
+ if (!header->isSectionHidden(i))
+ ++kid;
+ if (kid == child) {
+ logical = i;
+ break;
+ }
+ }
+ } else {
+ logical = child - 1;
+ }
+ return logical;
+}
+
+QRect QAccessibleItemRow::rect(int child) const
+{
+ QRect r;
+ if (view && view->isVisible()) {
+ if (QHeaderView *header = horizontalHeader()) {
+ if (!child) {
+ r = header->rect();
+ } else {
+ if (QHeaderView *vheader = verticalHeader()) {
+ if (child == 1) {
+ int w = vheader->width();
+ int h = header->height();
+ r.setRect(0, 0, w, h);
+ }
+ --child;
+ }
+ if (child) {
+ int logical = logicalFromChild(header, child);
+ int w = header->sectionSize(logical);
+ r.setRect(header->sectionViewportPosition(logical), 0, w, header->height());
+ r.translate(header->mapTo(view, QPoint(0, 0)));
+ }
+ }
+ } else if (row.isValid()) {
+ if (!child) {
+ QModelIndex parent = row.parent();
+ const int colCount = row.model()->columnCount(parent);
+ for (int i = 0; i < colCount; ++i)
+ r |= view->visualRect(row.model()->index(row.row(), i, parent));
+ r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
+
+ if (const QHeaderView *vheader = verticalHeader()) { // include the section of the vertical header
+ QRect re;
+ int logicalRow = row.row();
+ int h = vheader->sectionSize(logicalRow);
+ re.setRect(0, vheader->sectionViewportPosition(logicalRow), vheader->width(), h);
+ re.translate(vheader->mapTo(view, QPoint(0, 0)));
+ r |= re;
+ }
+ } else {
+ if (QHeaderView *vheader = verticalHeader()) {
+ if (child == 1) {
+ int logicalRow = row.row();
+ int h = vheader->sectionSize(logicalRow);
+ r.setRect(0, vheader->sectionViewportPosition(logicalRow), vheader->width(), h);
+ r.translate(vheader->mapTo(view, QPoint(0, 0)));
+ }
+ --child;
+ }
+ if (child) {
+ r = view->visualRect(childIndex(child));
+ r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
+ }
+ }
+ }
+ }
+ if (!r.isNull())
+ r.translate(view->mapToGlobal(QPoint(0, 0)));
+
+ return r;
+}
+
+int QAccessibleItemRow::treeLevel() const
+{
+ int level = 0;
+ QModelIndex idx = row;
+ while (idx.isValid()) {
+ idx = idx.parent();
+ ++level;
+ }
+ return level;
+}
+
+QString QAccessibleItemRow::text_helper(int child) const
+{
+ QString value;
+ if (m_header) {
+ if (!child)
+ return QString();
+ if (verticalHeader()) {
+ if (child == 1)
+ return QString();
+ --child;
+ }
+ QHeaderView *header = horizontalHeader();
+ int logical = logicalFromChild(header, child);
+ value = view->model()->headerData(logical, Qt::Horizontal, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = view->model()->headerData(logical, Qt::Horizontal).toString();
+ return value;
+ } else {
+ if (!child) { // for one-column views (i.e. QListView)
+ if (children().count() >= 1)
+ child = 1;
+ else
+ return QString();
+ }
+ if (verticalHeader()) {
+ if (child == 1) {
+ int logical = row.row();
+ value = view->model()->headerData(logical, Qt::Vertical, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = view->model()->headerData(logical, Qt::Vertical).toString();
+ return value;
+ } else {
+ --child;
+ }
+ }
+ }
+ if (value.isEmpty()) {
+ QModelIndex idx = childIndex(child);
+ if (idx.isValid()) {
+ value = idx.model()->data(idx, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = idx.model()->data(idx, Qt::DisplayRole).toString();
+ }
+ }
+ return value;
+}
+
+QString QAccessibleItemRow::text(Text t, int child) const
+{
+ QString value;
+ if (t == Name) {
+ value = text_helper(child);
+ } else if (t == Value) {
+#ifndef QT_NO_TREEVIEW
+ if (qobject_cast<const QTreeView*>(view)) {
+ if (child == 0)
+ value = QString::number(treeLevel());
+ } else
+#endif
+ {
+ value = text_helper(child);
+ }
+ } else if (t == Description) {
+#ifndef QT_NO_TREEVIEW
+ if (child == 0 && qobject_cast<const QTreeView*>(view)) {
+ // We store the tree coordinates of the current item in the description.
+ // This enables some screen readers to report where the focus is
+ // in a tree view. (works in JAWS). Also, Firefox does the same thing.
+ // For instance the description "L2, 4 of 25 with 24" means
+ // "L2": Tree Level 2
+ // "4 of 25": We are item 4 out of in total 25 other siblings
+ // "with 24": We have 24 children. (JAWS does not read this number)
+
+ // level
+ int level = treeLevel();
+
+ QAbstractItemModel *m = view->model();
+ // totalSiblings and itemIndex
+ QModelIndex parent = row.parent();
+ int rowCount = m->rowCount(parent);
+ int itemIndex = -1;
+ int totalSiblings = 0;
+ for (int i = 0 ; i < rowCount; ++i) {
+ QModelIndex sibling = row.sibling(i, 0);
+ if (!view->isIndexHidden(sibling))
+ ++totalSiblings;
+ if (row == sibling)
+ itemIndex = totalSiblings;
+ }
+ int totalChildren = m->rowCount(row); // JAWS does not report child count, so we do
+ // this simple and efficient.
+ // (don't check if they are all visible).
+ value = QString::fromAscii("L%1, %2 of %3 with %4").arg(level).arg(itemIndex).arg(totalSiblings).arg(totalChildren);
+ } else
+#endif // QT_NO_TREEVIEW
+ {
+ if (!m_header) {
+ if (child == 0 && children().count() >= 1)
+ child = 1;
+ if (verticalHeader()) {
+ if (child == 1) {
+ value = view->model()->headerData(row.row(), Qt::Vertical).toString();
+ }
+ --child;
+ }
+ if (child) {
+ QModelIndex idx = childIndex(child);
+ value = idx.model()->data(idx, Qt::AccessibleDescriptionRole).toString();
+ }
+
+ }
+ }
+ }
+ return value;
+}
+
+void QAccessibleItemRow::setText(Text t, int child, const QString &text)
+{
+ if (m_header) {
+ if (child)
+ view->model()->setHeaderData(child - 1, Qt::Horizontal, text);
+ // child == 0 means the cell to the left of the horizontal header, which is empty!?
+ } else {
+ if (!child) {
+ if (children().count() == 1)
+ child = 1;
+ else
+ return;
+ }
+
+ if (verticalHeader()) {
+ if (child == 1) {
+ view->model()->setHeaderData(row.row(), Qt::Vertical, text);
+ return;
+ }
+ --child;
+ }
+ QModelIndex idx = childIndex(child);
+ if (!idx.isValid())
+ return;
+
+ switch (t) {
+ case Description:
+ const_cast<QAbstractItemModel *>(idx.model())->setData(idx, text,
+ Qt::AccessibleDescriptionRole);
+ break;
+ case Value:
+ const_cast<QAbstractItemModel *>(idx.model())->setData(idx, text, Qt::EditRole);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+QModelIndex QAccessibleItemRow::childIndex(int child) const
+{
+ QList<QModelIndex> kids = children();
+ Q_ASSERT(child >= 1 && child <= kids.count());
+ return kids.at(child - 1);
+}
+
+QList<QModelIndex> QAccessibleItemRow::children() const
+{
+ QList<QModelIndex> kids;
+ for (int i = 0; i < row.model()->columnCount(row.parent()); ++i) {
+ QModelIndex idx = row.model()->index(row.row(), i, row.parent());
+ if (!view->isIndexHidden(idx)) {
+ kids << idx;
+ }
+ }
+ return kids;
+}
+
+bool QAccessibleItemRow::isValid() const
+{
+ return m_header ? true : row.isValid();
+}
+
+QObject *QAccessibleItemRow::object() const
+{
+ return 0;
+}
+
+int QAccessibleItemRow::childCount() const
+{
+ int count = 0;
+ if (QHeaderView *header = horizontalHeader()) {
+ count = header->count() - header->hiddenSectionCount();
+ } else {
+ count = children().count();
+ }
+#ifndef QT_NO_TABLEVIEW
+ if (qobject_cast<const QTableView*>(view)) {
+ if (verticalHeader())
+ ++count;
+ }
+#endif
+ return count;
+}
+
+int QAccessibleItemRow::indexOfChild(const QAccessibleInterface *iface) const
+{
+ if (!iface || iface->role(0) != Row)
+ return -1;
+
+ //### meaningless code?
+ QList<QModelIndex> kids = children();
+ QModelIndex idx = static_cast<const QAccessibleItemRow *>(iface)->row;
+ if (!idx.isValid())
+ return -1;
+ return kids.indexOf(idx) + 1;
+}
+
+QAccessible::Relation QAccessibleItemRow::relationTo(int child, const QAccessibleInterface *other,
+ int otherChild) const
+{
+ if (!child && !otherChild && other->object() == view)
+ return Child;
+ if (!child && !otherChild && other == this)
+ return Self;
+ if (!child && otherChild && other == this)
+ return Ancestor;
+ if (child && otherChild && other == this)
+ return Sibling;
+ return Unrelated;
+}
+
+int QAccessibleItemRow::childAt(int x, int y) const
+{
+ if (!view || !view->isVisible())
+ return -1;
+
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(x, y))
+ return i;
+ }
+ return -1;
+}
+
+QAbstractItemView::CursorAction QAccessibleItemRow::toCursorAction(
+ QAccessible::Relation rel)
+{
+ switch (rel) {
+ case QAccessible::Up:
+ return QAbstractItemView::MoveUp;
+ case QAccessible::Down:
+ return QAbstractItemView::MoveDown;
+ case QAccessible::Left:
+ return QAbstractItemView::MoveLeft;
+ case QAccessible::Right:
+ return QAbstractItemView::MoveRight;
+ default:
+ Q_ASSERT(false);
+ }
+ // should never be reached.
+ return QAbstractItemView::MoveRight;
+}
+
+int QAccessibleItemRow::navigate(RelationFlag relation, int index,
+ QAccessibleInterface **iface) const
+{
+ *iface = 0;
+ if (!view)
+ return -1;
+
+ switch (relation) {
+ case Ancestor: {
+ if (!index)
+ return -1;
+ QAccessibleItemView *ancestor = new QAccessibleItemView(view->viewport());
+ if (index == 1) {
+ *iface = ancestor;
+ return 0;
+ } else if (index > 1) {
+ int ret = ancestor->navigate(Ancestor, index - 1, iface);
+ delete ancestor;
+ return ret;
+ }
+ }
+ case Child: {
+ if (!index)
+ return -1;
+ if (index < 1 && index > childCount())
+ return -1;
+
+ return index;}
+ case Sibling:
+ if (index) {
+ QAccessibleInterface *ifaceParent = 0;
+ navigate(Ancestor, 1, &ifaceParent);
+ if (ifaceParent) {
+ int entry = ifaceParent->navigate(Child, index, iface);
+ delete ifaceParent;
+ return entry;
+ }
+ }
+ return -1;
+ case Up:
+ case Down:
+ case Left:
+ case Right: {
+ // This is in the "not so nice" category. In order to find out which item
+ // is geometrically around, we have to set the current index, navigate
+ // and restore the index as well as the old selection
+ view->setUpdatesEnabled(false);
+ const QModelIndex oldIdx = view->currentIndex();
+ QList<QModelIndex> kids = children();
+ const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row);
+ const QItemSelection oldSelection = view->selectionModel()->selection();
+ view->setCurrentIndex(currentIndex);
+ const QModelIndex idx = view->moveCursor(toCursorAction(relation), Qt::NoModifier);
+ view->setCurrentIndex(oldIdx);
+ view->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect);
+ view->setUpdatesEnabled(true);
+ if (!idx.isValid())
+ return -1;
+
+ if (idx.parent() != row.parent() || idx.row() != row.row())
+ *iface = new QAccessibleItemRow(view, idx);
+ return index ? kids.indexOf(idx) + 1 : 0; }
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+QAccessible::Role QAccessibleItemRow::role(int child) const
+{
+ if (false) {
+#ifndef QT_NO_TREEVIEW
+ } else if (qobject_cast<const QTreeView*>(view)) {
+ if (horizontalHeader()) {
+ if (!child)
+ return Row;
+ return ColumnHeader;
+ }
+ return TreeItem;
+#endif
+#ifndef QT_NO_LISTVIEW
+ } else if (qobject_cast<const QListView*>(view)) {
+ return ListItem;
+#endif
+#ifndef QT_NO_TABLEVIEW
+ } else if (qobject_cast<const QTableView *>(view)) {
+ if (!child)
+ return Row;
+ if (child == 1) {
+ if (verticalHeader())
+ return RowHeader;
+ }
+ if (m_header)
+ return ColumnHeader;
+#endif
+ }
+ return Cell;
+}
+
+QAccessible::State QAccessibleItemRow::state(int child) const
+{
+ State st = Normal;
+
+ if (!view)
+ return st;
+
+ QAccessibleInterface *parent = 0;
+ QRect globalRect;
+ if (navigate(Ancestor, 1, &parent) == 0) {
+ globalRect = parent->rect(0);
+ delete parent;
+ }
+ if (!globalRect.intersects(rect(child)))
+ st |= Invisible;
+
+ if (!horizontalHeader()) {
+ if (!(st & Invisible)) {
+ if (child) {
+ if (QHeaderView *vheader = verticalHeader() ) {
+ if (child == 1) {
+ if (!vheader->isVisible())
+ st |= Invisible;
+ }
+ --child;
+ }
+ if (child) {
+ QModelIndex idx = childIndex(child);
+ if (!idx.isValid())
+ return st;
+
+ if (view->selectionModel()->isSelected(idx))
+ st |= Selected;
+ if (view->selectionModel()->currentIndex() == idx)
+ st |= Focused;
+ if (idx.model()->data(idx, Qt::CheckStateRole).toInt() == Qt::Checked)
+ st |= Checked;
+
+ Qt::ItemFlags flags = idx.flags();
+ if (flags & Qt::ItemIsSelectable) {
+ st |= Selectable;
+ if (view->selectionMode() == QAbstractItemView::MultiSelection)
+ st |= MultiSelectable;
+ if (view->selectionMode() == QAbstractItemView::ExtendedSelection)
+ st |= ExtSelectable;
+ }
+ }
+ } else {
+ Qt::ItemFlags flags = row.flags();
+ if (flags & Qt::ItemIsSelectable) {
+ st |= Selectable;
+ st |= Focusable;
+ }
+ if (view->selectionModel()->isRowSelected(row.row(), row.parent()))
+ st |= Selected;
+ if (view->selectionModel()->currentIndex().row() == row.row())
+ st |= Focused;
+ }
+ }
+ }
+
+ return st;
+}
+
+int QAccessibleItemRow::userActionCount(int) const
+{
+ return 0;
+}
+
+QString QAccessibleItemRow::actionText(int, Text, int) const
+{
+ return QString();
+}
+
+static QItemSelection rowAt(const QModelIndex &idx)
+{
+ return QItemSelection(idx.sibling(idx.row(), 0),
+ idx.sibling(idx.row(), idx.model()->columnCount(idx.parent())));
+}
+
+bool QAccessibleItemRow::doAction(int action, int child, const QVariantList & /*params*/)
+{
+ if (!view)
+ return false;
+
+ if (verticalHeader())
+ --child;
+
+ QModelIndex idx = child ? childIndex(child) : QModelIndex(row);
+ if (!idx.isValid())
+ return false;
+
+ QItemSelectionModel::SelectionFlags command = QItemSelectionModel::NoUpdate;
+
+ switch (action) {
+ case SetFocus:
+ view->setCurrentIndex(idx);
+ return true;
+ case ExtendSelection:
+ if (!child)
+ return false;
+ view->selectionModel()->select(QItemSelection(view->currentIndex(), idx),
+ QItemSelectionModel::SelectCurrent);
+ return true;
+ case Select:
+ command = QItemSelectionModel::ClearAndSelect;
+ break;
+ case ClearSelection:
+ command = QItemSelectionModel::Clear;
+ break;
+ case RemoveSelection:
+ command = QItemSelectionModel::Deselect;
+ break;
+ case AddToSelection:
+ command = QItemSelectionModel::SelectCurrent;
+ break;
+ }
+ if (command == QItemSelectionModel::NoUpdate)
+ return false;
+
+ if (child)
+ view->selectionModel()->select(idx, command);
+ else
+ view->selectionModel()->select(rowAt(row), command);
+ return true;
+}
+
+class ModelIndexIterator
+{
+public:
+ ModelIndexIterator(QAbstractItemView *view, const QModelIndex &start = QModelIndex()) : m_view(view)
+ {
+#ifndef QT_NO_LISTVIEW
+ list = qobject_cast<QListView*>(m_view);
+#endif
+#ifndef QT_NO_TREEVIEW
+ tree = qobject_cast<QTreeView*>(m_view);
+#endif
+#ifndef QT_NO_TABLEVIEW
+ table = qobject_cast<QTableView*>(m_view);
+#endif
+ if (start.isValid()) {
+ m_current = start;
+ } else if (m_view && m_view->model()) {
+ m_current = view->rootIndex().isValid() ?
+ view->rootIndex().child(0,0) : view->model()->index(0, 0);
+ }
+ }
+
+ bool next(int count = 1) {
+ for (int i = 0; i < count; ++i) {
+ do {
+ if (m_current.isValid()) {
+ const QAbstractItemModel *m = m_current.model();
+#ifndef QT_NO_TREEVIEW
+ if (tree && m_current.model()->hasChildren(m_current) && tree->isExpanded(m_current)) {
+ m_current = m_current.child(0, 0);
+ } else
+#endif
+ {
+ int row = m_current.row();
+ QModelIndex par = m_current.parent();
+
+ // Go up to the parent if we reach the end of the rows
+ // If m_curent becomses invalid, stop going up.
+ while (row + 1 >= m->rowCount(par)) {
+ m_current = par;
+ if (m_current.isValid()) {
+ row = m_current.row();
+ par = m_current.parent();
+ } else {
+ row = 0;
+ par = QModelIndex();
+ break;
+ }
+ }
+
+ if (m_current.isValid())
+ m_current = m_current.sibling(row + 1, 0);
+ }
+ }
+ } while (isHidden());
+ }
+ return m_current.isValid();
+ }
+
+ bool isHidden() const {
+ if (false) {
+#ifndef QT_NO_LISTVIEW
+ } else if (list) {
+ return list->isRowHidden(m_current.row());
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (tree) {
+ return tree->isRowHidden(m_current.row(), m_current.parent());
+#endif
+#ifndef QT_NO_TABLEVIEW
+ } else if (table) {
+ return table->isRowHidden(m_current.row());
+#endif
+ }
+ return false;
+ }
+
+ QModelIndex current() const {
+ return m_current;
+ }
+
+private:
+ QModelIndex m_current;
+ QAbstractItemView *m_view;
+
+#ifndef QT_NO_TREEVIEW
+ QTreeView *tree;
+#endif
+#ifndef QT_NO_LISTVIEW
+ QListView *list;
+#endif
+#ifndef QT_NO_TABLEVIEW
+ QTableView *table;
+#endif
+};
+
+QAccessibleItemView::QAccessibleItemView(QWidget *w)
+ : QAccessibleAbstractScrollArea(w->objectName() == QLatin1String("qt_scrollarea_viewport") ? w->parentWidget() : w)
+{
+ atVP = w->objectName() == QLatin1String("qt_scrollarea_viewport");
+
+}
+
+
+QHeaderView *QAccessibleItemView::horizontalHeader() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(itemView())) {
+ header = tv->horizontalHeader();
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(itemView())) {
+ header = tv->header();
+#endif
+ }
+ return header;
+}
+
+QHeaderView *QAccessibleItemView::verticalHeader() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(itemView())) {
+ header = tv->verticalHeader();
+#endif
+ }
+ return header;
+}
+
+
+bool QAccessibleItemView::isValidChildRole(QAccessible::Role role) const
+{
+ if (atViewport()) {
+ if (false) {
+#ifndef QT_NO_TREEVIEW
+ } else if (qobject_cast<const QTreeView*>(itemView())) {
+ return (role == TreeItem || role == Row);
+#endif
+#ifndef QT_NO_LISTVIEW
+ } else if (qobject_cast<const QListView*>(itemView())) {
+ return (role == ListItem);
+#endif
+ }
+ // TableView
+ return role == Row;
+ } else {
+ if (false) {
+#ifndef QT_NO_TREEVIEW
+ } else if (qobject_cast<const QTreeView*>(itemView())) {
+ return (role == Tree);
+#endif
+#ifndef QT_NO_LISTVIEW
+ } else if (qobject_cast<const QListView*>(itemView())) {
+ return (role == List);
+#endif
+ }
+ // TableView
+ return (role == Table);
+ }
+}
+
+QObject *QAccessibleItemView::object() const
+{
+ QObject *view = QAccessibleAbstractScrollArea::object();
+ Q_ASSERT(qobject_cast<const QAbstractItemView *>(view));
+ if (atViewport())
+ view = qobject_cast<const QAbstractItemView *>(view)->viewport();
+ return view;
+}
+
+QAbstractItemView *QAccessibleItemView::itemView() const
+{
+ return qobject_cast<QAbstractItemView *>(QAccessibleAbstractScrollArea::object());
+}
+
+int QAccessibleItemView::indexOfChild(const QAccessibleInterface *iface) const
+{
+ if (atViewport()) {
+ if (!iface || !isValidChildRole(iface->role(0)))
+ return -1;
+
+ int entry = -1;
+ // ### This will fail if a row is hidden.
+ const QAccessibleItemRow *ifRow = static_cast<const QAccessibleItemRow *>(iface);
+ if (ifRow->horizontalHeader())
+ return 1;
+
+ QModelIndex idx = ifRow->row;
+ if (!idx.isValid())
+ return -1;
+
+ entry = entryFromIndex(idx);
+ if (horizontalHeader())
+ ++entry;
+
+ return entry;
+
+ } else {
+ return QAccessibleAbstractScrollArea::indexOfChild(iface);
+ }
+}
+
+QModelIndex QAccessibleItemView::childIndex(int child) const
+{
+ if (!atViewport())
+ return QModelIndex();
+ ModelIndexIterator it(itemView());
+ it.next(child - 1);
+ return it.current();
+}
+
+int QAccessibleItemView::entryFromIndex(const QModelIndex &index) const
+{
+ int entry = -1;
+ if (false) {
+#ifndef QT_NO_TREEVIEW
+ } else if (QTreeView *tree = qobject_cast<QTreeView*>(itemView())) {
+ entry = tree->visualIndex(index) + 1;
+#endif
+#ifndef QT_NO_LISTVIEW
+ } else if (QListView *list = qobject_cast<QListView*>(itemView())) {
+ entry = list->visualIndex(index) + 1;
+#endif
+#ifndef QT_NO_TABLEVIEW
+ } else if (QTableView *table = qobject_cast<QTableView*>(itemView())) {
+ entry = table->visualIndex(index) + 1;
+#endif
+ }
+ return entry;
+}
+
+int QAccessibleItemView::childCount() const
+{
+ if (atViewport()) {
+ if (itemView()->model() == 0)
+ return 0;
+ QAbstractItemModel *m = itemView()->model();
+ QModelIndex idx = m->index(0,0);
+ if (!idx.isValid())
+ return 0;
+ ModelIndexIterator it(itemView());
+ int count = 1;
+ while (it.next()) {
+ ++count;
+ }
+ if (horizontalHeader())
+ ++count;
+
+ return count;
+ } else {
+ return QAccessibleAbstractScrollArea::childCount();
+ }
+}
+
+QString QAccessibleItemView::text(Text t, int child) const
+{
+ if (atViewport()) {
+ if (!child)
+ return QAccessibleAbstractScrollArea::text(t, child);
+
+ QAccessibleItemRow item(itemView(), childIndex(child));
+ return item.text(t, 1);
+ } else {
+ return QAccessibleAbstractScrollArea::text(t, child);
+ }
+}
+
+void QAccessibleItemView::setText(Text t, int child, const QString &text)
+{
+ if (atViewport()) {
+ if (!child) {
+ QAccessibleAbstractScrollArea::setText(t, child, text);
+ return;
+ }
+
+ QAccessibleItemRow item(itemView(), childIndex(child));
+ item.setText(t, 1, text);
+ } else {
+ QAccessibleAbstractScrollArea::setText(t, child, text);
+ }
+}
+
+QRect QAccessibleItemView::rect(int child) const
+{
+ if (atViewport()) {
+ QRect r;
+ if (!child) {
+ // Make sure that the rect *include* the vertical and horizontal headers, while
+ // not including the potential vertical and horizontal scrollbars.
+ QAbstractItemView *w = itemView();
+
+ int vscrollWidth = 0;
+ const QScrollBar *sb = w->verticalScrollBar();
+ if (sb && sb->isVisible())
+ vscrollWidth = sb->width();
+
+ int hscrollHeight = 0;
+ sb = w->horizontalScrollBar();
+ if (sb && sb->isVisible())
+ hscrollHeight = sb->height();
+
+ QPoint globalPos = w->mapToGlobal(QPoint(0,0));
+ r = w->rect().translated(globalPos);
+ if (w->isRightToLeft()) {
+ r.adjust(vscrollWidth, 0, 0, -hscrollHeight);
+ } else {
+ r.adjust(0, 0, -vscrollWidth, -hscrollHeight);
+ }
+ } else {
+ QAccessibleInterface *iface = 0;
+ if (navigate(Child, child, &iface) == 0) {
+ r = iface->rect(0);
+ delete iface;
+ }
+ }
+ return r;
+ } else {
+ QRect r = QAccessibleAbstractScrollArea::rect(child);
+ if (child == 1) {
+ // include the potential vertical and horizontal headers
+
+ const QHeaderView *header = verticalHeader();
+ int headerWidth = (header && header->isVisible()) ? header->width() : 0;
+ header = horizontalHeader();
+ int headerHeight= (header && header->isVisible()) ? header->height() : 0;
+ if (itemView()->isRightToLeft()) {
+ r.adjust(0, -headerHeight, headerWidth, 0);
+ } else {
+ r.adjust(-headerWidth, -headerHeight, 0, 0);
+ }
+ }
+ return r;
+ }
+}
+
+int QAccessibleItemView::childAt(int x, int y) const
+{
+ if (atViewport()) {
+ QPoint p(x, y);
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(p))
+ return i;
+ }
+ return -1;
+ } else {
+ return QAccessibleAbstractScrollArea::childAt(x, y);
+ }
+}
+
+QAccessible::Role QAccessibleItemView::role(int child) const
+{
+ if ((!atViewport() && child) || (atViewport() && child == 0)) {
+ QAbstractItemView *view = itemView();
+#ifndef QT_NO_TABLEVIEW
+ if (qobject_cast<QTableView *>(view))
+ return Table;
+#endif
+#ifndef QT_NO_LISTVIEW
+ if (qobject_cast<QListView *>(view))
+ return List;
+#endif
+ return Tree;
+ }
+ if (atViewport()) {
+ if (child)
+ return Row;
+ }
+
+ return QAccessibleAbstractScrollArea::role(child);
+}
+
+QAccessible::State QAccessibleItemView::state(int child) const
+{
+ State st = Normal;
+
+ if (itemView() == 0)
+ return State(Unavailable);
+
+ bool queryViewPort = (atViewport() && child == 0) || (!atViewport() && child == 1);
+ if (queryViewPort) {
+ if (itemView()->selectionMode() != QAbstractItemView::NoSelection) {
+ st |= Selectable;
+ st |= Focusable;
+ }
+ } else if (atViewport()) { // children of viewport
+ if (horizontalHeader())
+ --child;
+ if (child) {
+ QAccessibleItemRow item(itemView(), childIndex(child));
+ st |= item.state(0);
+ }
+ } else if (!atViewport() && child != 1) {
+ st = QAccessibleAbstractScrollArea::state(child);
+ }
+ return st;
+}
+
+bool QAccessibleItemView::isValid() const
+{
+ if (atViewport())
+ return QAccessibleWidgetEx::isValid();
+ else
+ return QAccessibleAbstractScrollArea::isValid();
+}
+
+int QAccessibleItemView::navigate(RelationFlag relation, int index,
+ QAccessibleInterface **iface) const
+{
+ if (atViewport()) {
+ if (relation == Ancestor && index == 1) {
+ *iface = new QAccessibleItemView(itemView());
+ return 0;
+ } else if (relation == Child && index >= 1) {
+ if (horizontalHeader()) {
+ if (index == 1) {
+ *iface = new QAccessibleItemRow(itemView(), QModelIndex(), true);
+ return 0;
+ }
+ --index;
+ }
+
+ //###JAS hidden rows..
+ QModelIndex idx = childIndex(index);
+ if (idx.isValid()) {
+ *iface = new QAccessibleItemRow(itemView(), idx);
+ return 0;
+ }
+ } else if (relation == Sibling && index >= 1) {
+ QAccessibleInterface *parent = new QAccessibleItemView(itemView());
+ return parent->navigate(Child, index, iface);
+ }
+ *iface = 0;
+ return -1;
+ } else {
+ return QAccessibleAbstractScrollArea::navigate(relation, index, iface);
+ }
+}
+
+/* returns the model index for a given row and column */
+QModelIndex QAccessibleItemView::index(int row, int column) const
+{
+ return itemView()->model()->index(row, column);
+}
+
+QAccessibleInterface *QAccessibleItemView::accessibleAt(int row, int column)
+{
+ QWidget *indexWidget = itemView()->indexWidget(index(row, column));
+ return QAccessible::queryAccessibleInterface(indexWidget);
+}
+
+/* We don't have a concept of a "caption" in Qt's standard widgets */
+QAccessibleInterface *QAccessibleItemView::caption()
+{
+ return 0;
+}
+
+/* childIndex is row * columnCount + columnIndex */
+int QAccessibleItemView::childIndex(int rowIndex, int columnIndex)
+{
+ return rowIndex * itemView()->model()->columnCount() + columnIndex;
+}
+
+/* Return the header data as column description */
+QString QAccessibleItemView::columnDescription(int column)
+{
+ return itemView()->model()->headerData(column, Qt::Horizontal).toString();
+}
+
+/* We don't support column spanning atm */
+int QAccessibleItemView::columnSpan(int /* row */, int /* column */)
+{
+ return 1;
+}
+
+/* Return the horizontal header view */
+QAccessibleInterface *QAccessibleItemView::columnHeader()
+{
+#ifndef QT_NO_TREEVIEW
+ if (QTreeView *tree = qobject_cast<QTreeView *>(itemView()))
+ return QAccessible::queryAccessibleInterface(tree->header());
+#endif
+#ifndef QT_NO_TABLEVIEW
+ if (QTableView *table = qobject_cast<QTableView *>(itemView()))
+ return QAccessible::queryAccessibleInterface(table->horizontalHeader());
+#endif
+ return 0;
+}
+
+int QAccessibleItemView::columnIndex(int childIndex)
+{
+ int columnCount = itemView()->model()->columnCount();
+ if (!columnCount)
+ return 0;
+
+ return childIndex % columnCount;
+}
+
+int QAccessibleItemView::columnCount()
+{
+ return itemView()->model()->columnCount();
+}
+
+int QAccessibleItemView::rowCount()
+{
+ return itemView()->model()->rowCount();
+}
+
+int QAccessibleItemView::selectedColumnCount()
+{
+ return itemView()->selectionModel()->selectedColumns().count();
+}
+
+int QAccessibleItemView::selectedRowCount()
+{
+ return itemView()->selectionModel()->selectedRows().count();
+}
+
+QString QAccessibleItemView::rowDescription(int row)
+{
+ return itemView()->model()->headerData(row, Qt::Vertical).toString();
+}
+
+/* We don't support row spanning */
+int QAccessibleItemView::rowSpan(int /*row*/, int /*column*/)
+{
+ return 1;
+}
+
+QAccessibleInterface *QAccessibleItemView::rowHeader()
+{
+#ifndef QT_NO_TABLEVIEW
+ if (QTableView *table = qobject_cast<QTableView *>(itemView()))
+ return QAccessible::queryAccessibleInterface(table->verticalHeader());
+#endif
+ return 0;
+}
+
+int QAccessibleItemView::rowIndex(int childIndex)
+{
+ int columnCount = itemView()->model()->columnCount();
+ if (!columnCount)
+ return 0;
+
+ return int(childIndex / columnCount);
+}
+
+int QAccessibleItemView::selectedRows(int maxRows, QList<int> *rows)
+{
+ Q_ASSERT(rows);
+
+ const QModelIndexList selRows = itemView()->selectionModel()->selectedRows();
+ int maxCount = qMin(selRows.count(), maxRows);
+
+ for (int i = 0; i < maxCount; ++i)
+ rows->append(selRows.at(i).row());
+
+ return maxCount;
+}
+
+int QAccessibleItemView::selectedColumns(int maxColumns, QList<int> *columns)
+{
+ Q_ASSERT(columns);
+
+ const QModelIndexList selColumns = itemView()->selectionModel()->selectedColumns();
+ int maxCount = qMin(selColumns.count(), maxColumns);
+
+ for (int i = 0; i < maxCount; ++i)
+ columns->append(selColumns.at(i).row());
+
+ return maxCount;
+}
+
+/* Qt widgets don't have a concept of a summary */
+QAccessibleInterface *QAccessibleItemView::summary()
+{
+ return 0;
+}
+
+bool QAccessibleItemView::isColumnSelected(int column)
+{
+ return itemView()->selectionModel()->isColumnSelected(column, QModelIndex());
+}
+
+bool QAccessibleItemView::isRowSelected(int row)
+{
+ return itemView()->selectionModel()->isRowSelected(row, QModelIndex());
+}
+
+bool QAccessibleItemView::isSelected(int row, int column)
+{
+ return itemView()->selectionModel()->isSelected(index(row, column));
+}
+
+void QAccessibleItemView::selectRow(int row)
+{
+ QItemSelectionModel *s = itemView()->selectionModel();
+ s->select(index(row, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows);
+}
+
+void QAccessibleItemView::selectColumn(int column)
+{
+ QItemSelectionModel *s = itemView()->selectionModel();
+ s->select(index(0, column), QItemSelectionModel::Select | QItemSelectionModel::Columns);
+}
+
+void QAccessibleItemView::unselectRow(int row)
+{
+ QItemSelectionModel *s = itemView()->selectionModel();
+ s->select(index(row, 0), QItemSelectionModel::Deselect | QItemSelectionModel::Rows);
+}
+
+void QAccessibleItemView::unselectColumn(int column)
+{
+ QItemSelectionModel *s = itemView()->selectionModel();
+ s->select(index(0, column), QItemSelectionModel::Deselect | QItemSelectionModel::Columns);
+}
+
+void QAccessibleItemView::cellAtIndex(int index, int *row, int *column, int *rSpan,
+ int *cSpan, bool *isSelect)
+{
+ *row = rowIndex(index);
+ *column = columnIndex(index);
+ *rSpan = rowSpan(*row, *column);
+ *cSpan = columnSpan(*row, *column);
+ *isSelect = isSelected(*row, *column);
+}
+
+/*!
+ \class QAccessibleHeader
+ \brief The QAccessibleHeader class implements the QAccessibleInterface for header widgets.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleHeader object for \a w.
+*/
+QAccessibleHeader::QAccessibleHeader(QWidget *w)
+: QAccessibleWidgetEx(w)
+{
+ Q_ASSERT(header());
+ addControllingSignal(QLatin1String("sectionClicked(int)"));
+}
+
+/*! Returns the QHeaderView. */
+QHeaderView *QAccessibleHeader::header() const
+{
+ return qobject_cast<QHeaderView*>(object());
+}
+
+/*! \reimp */
+QRect QAccessibleHeader::rect(int child) const
+{
+ if (!child)
+ return QAccessibleWidgetEx::rect(0);
+
+ QHeaderView *h = header();
+ QPoint zero = h->mapToGlobal(QPoint(0, 0));
+ int sectionSize = h->sectionSize(child - 1);
+ int sectionPos = h->sectionPosition(child - 1);
+ return h->orientation() == Qt::Horizontal
+ ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, h->height())
+ : QRect(zero.x(), zero.y() + sectionPos, h->width(), sectionSize);
+}
+
+/*! \reimp */
+int QAccessibleHeader::childCount() const
+{
+ return header()->count();
+}
+
+/*! \reimp */
+QString QAccessibleHeader::text(Text t, int child) const
+{
+ QString str;
+
+ if (child > 0 && child <= childCount()) {
+ switch (t) {
+ case Name:
+ str = header()->model()->headerData(child - 1, header()->orientation()).toString();
+ break;
+ case Description: {
+ QAccessibleEvent event(QEvent::AccessibilityDescription, child);
+ if (QApplication::sendEvent(widget(), &event))
+ str = event.value();
+ break; }
+ case Help: {
+ QAccessibleEvent event(QEvent::AccessibilityHelp, child);
+ if (QApplication::sendEvent(widget(), &event))
+ str = event.value();
+ break; }
+ default:
+ break;
+ }
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, child);
+ return str;
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleHeader::role(int) const
+{
+ return (header()->orientation() == Qt::Horizontal) ? ColumnHeader : RowHeader;
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleHeader::state(int child) const
+{
+ State state = QAccessibleWidgetEx::state(child);
+
+ if (child) {
+ int section = child - 1;
+ if (header()->isSectionHidden(section))
+ state |= Invisible;
+ if (header()->resizeMode(section) != QHeaderView::Custom)
+ state |= Sizeable;
+ } else {
+ if (header()->isMovable())
+ state |= Movable;
+ }
+ if (!header()->isClickable())
+ state |= Unavailable;
+ return state;
+}
+#endif // QT_NO_ITEMVIEWS
+
+#ifndef QT_NO_TABBAR
+/*!
+ \class QAccessibleTabBar
+ \brief The QAccessibleTabBar class implements the QAccessibleInterface for tab bars.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleTabBar object for \a w.
+*/
+QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
+: QAccessibleWidgetEx(w)
+{
+ Q_ASSERT(tabBar());
+}
+
+/*! Returns the QTabBar. */
+QTabBar *QAccessibleTabBar::tabBar() const
+{
+ return qobject_cast<QTabBar*>(object());
+}
+
+QAbstractButton *QAccessibleTabBar::button(int child) const
+{
+ if (child <= tabBar()->count())
+ return 0;
+ QTabBarPrivate * const tabBarPrivate = tabBar()->d_func();
+ if (child - tabBar()->count() == 1)
+ return tabBarPrivate->leftB;
+ if (child - tabBar()->count() == 2)
+ return tabBarPrivate->rightB;
+ Q_ASSERT(false);
+ return 0;
+}
+
+/*! \reimp */
+QRect QAccessibleTabBar::rect(int child) const
+{
+ if (!child || !tabBar()->isVisible())
+ return QAccessibleWidgetEx::rect(0);
+
+ QPoint tp = tabBar()->mapToGlobal(QPoint(0,0));
+ QRect rec;
+ if (child <= tabBar()->count()) {
+ rec = tabBar()->tabRect(child - 1);
+ } else {
+ QWidget *widget = button(child);
+ rec = widget ? widget->geometry() : QRect();
+ }
+ return QRect(tp.x() + rec.x(), tp.y() + rec.y(), rec.width(), rec.height());
+}
+
+/*! \reimp */
+int QAccessibleTabBar::childCount() const
+{
+ // tabs + scroll buttons
+ return tabBar()->count() + 2;
+}
+
+/*! \reimp */
+QString QAccessibleTabBar::text(Text t, int child) const
+{
+ QString str;
+
+ if (child > tabBar()->count()) {
+ bool left = child - tabBar()->count() == 1;
+ switch (t) {
+ case Name:
+ return left ? QTabBar::tr("Scroll Left") : QTabBar::tr("Scroll Right");
+ default:
+ break;
+ }
+ } else {
+ switch (t) {
+ case Name:
+ if (child > 0)
+ return qt_accStripAmp(tabBar()->tabText(child - 1));
+ else if (tabBar()->currentIndex() != -1)
+ return qt_accStripAmp(tabBar()->tabText(tabBar()->currentIndex()));
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, child);;
+ return str;
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleTabBar::role(int child) const
+{
+ if (!child)
+ return PageTabList;
+ if (child > tabBar()->count())
+ return PushButton;
+ return PageTab;
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleTabBar::state(int child) const
+{
+ State st = QAccessibleWidgetEx::state(0);
+
+ if (!child)
+ return st;
+
+ QTabBar *tb = tabBar();
+
+ if (child > tb->count()) {
+ QWidget *bt = button(child);
+ if (!bt)
+ return st;
+ if (bt->isEnabled() == false)
+ st |= Unavailable;
+ if (bt->isVisible() == false)
+ st |= Invisible;
+ if (bt->focusPolicy() != Qt::NoFocus && bt->isActiveWindow())
+ st |= Focusable;
+ if (bt->hasFocus())
+ st |= Focused;
+ return st;
+ }
+
+ if (!tb->isTabEnabled(child - 1))
+ st |= Unavailable;
+ else
+ st |= Selectable;
+
+ if (!tb->currentIndex() == child - 1)
+ st |= Selected;
+
+ return st;
+}
+
+/*! \reimp */
+bool QAccessibleTabBar::doAction(int action, int child, const QVariantList &)
+{
+ if (!child)
+ return false;
+
+ if (action != QAccessible::DefaultAction && action != QAccessible::Press)
+ return false;
+
+ if (child > tabBar()->count()) {
+ QAbstractButton *bt = button(child);
+ if (!bt->isEnabled())
+ return false;
+ bt->animateClick();
+ return true;
+ }
+ if (!tabBar()->isTabEnabled(child - 1))
+ return false;
+ tabBar()->setCurrentIndex(child - 1);
+ return true;
+}
+
+/*!
+ Selects the item with index \a child if \a on is true; otherwise
+ unselects it. If \a extend is true and the selection mode is not
+ \c Single and there is an existing selection, the selection is
+ extended to include all the items from the existing selection up
+ to and including the item with index \a child. Returns true if a
+ selection was made or extended; otherwise returns false.
+
+ \sa selection() clearSelection()
+*/
+bool QAccessibleTabBar::setSelected(int child, bool on, bool extend)
+{
+ if (!child || !on || extend || child > tabBar()->count())
+ return false;
+
+ if (!tabBar()->isTabEnabled(child - 1))
+ return false;
+ tabBar()->setCurrentIndex(child - 1);
+ return true;
+}
+
+/*!
+ Returns a (possibly empty) list of indexes of the items selected
+ in the list box.
+
+ \sa setSelected() clearSelection()
+*/
+QVector<int> QAccessibleTabBar::selection() const
+{
+ QVector<int> array;
+ if (tabBar()->currentIndex() != -1)
+ array +=tabBar()->currentIndex() + 1;
+ return array;
+}
+
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_COMBOBOX
+/*!
+ \class QAccessibleComboBox
+ \brief The QAccessibleComboBox class implements the QAccessibleInterface for editable and read-only combo boxes.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ \enum QAccessibleComboBox::ComboBoxElements
+
+ \internal
+
+ \value ComboBoxSelf
+ \value CurrentText
+ \value OpenList
+ \value PopupList
+*/
+
+/*!
+ Constructs a QAccessibleComboBox object for \a w.
+*/
+QAccessibleComboBox::QAccessibleComboBox(QWidget *w)
+: QAccessibleWidgetEx(w, ComboBox)
+{
+ Q_ASSERT(comboBox());
+}
+
+/*!
+ Returns the combobox.
+*/
+QComboBox *QAccessibleComboBox::comboBox() const
+{
+ return qobject_cast<QComboBox*>(object());
+}
+
+/*! \reimp */
+QRect QAccessibleComboBox::rect(int child) const
+{
+ QPoint tp;
+ QStyle::SubControl sc;
+ QRect r;
+ switch (child) {
+ case CurrentText:
+ if (comboBox()->isEditable()) {
+ tp = comboBox()->lineEdit()->mapToGlobal(QPoint(0,0));
+ r = comboBox()->lineEdit()->rect();
+ sc = QStyle::SC_None;
+ } else {
+ tp = comboBox()->mapToGlobal(QPoint(0,0));
+ sc = QStyle::SC_ComboBoxEditField;
+ }
+ break;
+ case OpenList:
+ tp = comboBox()->mapToGlobal(QPoint(0,0));
+ sc = QStyle::SC_ComboBoxArrow;
+ break;
+ default:
+ return QAccessibleWidgetEx::rect(child);
+ }
+
+ if (sc != QStyle::SC_None) {
+ QStyleOptionComboBox option;
+ option.initFrom(comboBox());
+ r = comboBox()->style()->subControlRect(QStyle::CC_ComboBox, &option, sc, comboBox());
+ }
+ return QRect(tp.x() + r.x(), tp.y() + r.y(), r.width(), r.height());
+}
+
+/*! \reimp */
+int QAccessibleComboBox::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+ if (entry > ComboBoxSelf) switch (rel) {
+ case Child:
+ if (entry < PopupList)
+ return entry;
+ if (entry == PopupList) {
+ QAbstractItemView *view = comboBox()->view();
+ QWidget *parent = view ? view->parentWidget() : 0;
+ *target = QAccessible::queryAccessibleInterface(parent);
+ return *target ? 0 : -1;
+ }
+ case QAccessible::Left:
+ return entry == OpenList ? CurrentText : -1;
+ case QAccessible::Right:
+ return entry == CurrentText ? OpenList : -1;
+ case QAccessible::Up:
+ return -1;
+ case QAccessible::Down:
+ return -1;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::navigate(rel, entry, target);
+}
+
+/*! \reimp */
+int QAccessibleComboBox::childCount() const
+{
+ return comboBox()->view() ? PopupList : OpenList;
+}
+
+/*! \reimp */
+int QAccessibleComboBox::childAt(int x, int y) const
+{
+ if (!comboBox()->isVisible())
+ return -1;
+ QPoint gp = widget()->mapToGlobal(QPoint(0, 0));
+ if (!QRect(gp.x(), gp.y(), widget()->width(), widget()->height()).contains(x, y))
+ return -1;
+
+ // a complex control
+ for (int i = 1; i < PopupList; ++i) {
+ if (rect(i).contains(x, y))
+ return i;
+ }
+ return 0;
+}
+
+/*! \reimp */
+int QAccessibleComboBox::indexOfChild(const QAccessibleInterface *child) const
+{
+ QObject *viewParent = comboBox()->view() ? comboBox()->view()->parentWidget() : 0;
+ if (child->object() == viewParent)
+ return PopupList;
+ return -1;
+}
+
+/*! \reimp */
+QString QAccessibleComboBox::text(Text t, int child) const
+{
+ QString str;
+
+ switch (t) {
+ case Name:
+ if (child == OpenList)
+ str = QComboBox::tr("Open");
+ else
+ str = QAccessibleWidgetEx::text(t, 0);
+ break;
+#ifndef QT_NO_SHORTCUT
+ case Accelerator:
+ if (child == OpenList)
+ str = (QString)QKeySequence(Qt::Key_Down);
+ // missing break?
+#endif
+ case Value:
+ if (comboBox()->isEditable())
+ str = comboBox()->lineEdit()->text();
+ else
+ str = comboBox()->currentText();
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, 0);
+ return str;
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleComboBox::role(int child) const
+{
+ switch (child) {
+ case CurrentText:
+ if (comboBox()->isEditable())
+ return EditableText;
+ return StaticText;
+ case OpenList:
+ return PushButton;
+ case PopupList:
+ return List;
+ default:
+ return ComboBox;
+ }
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleComboBox::state(int /*child*/) const
+{
+ return QAccessibleWidgetEx::state(0);
+}
+
+/*! \reimp */
+bool QAccessibleComboBox::doAction(int action, int child, const QVariantList &)
+{
+ if (child == 2 && (action == DefaultAction || action == Press)) {
+ if (comboBox()->view()->isVisible()) {
+ comboBox()->hidePopup();
+ } else {
+ comboBox()->showPopup();
+ }
+ return true;
+ }
+ return false;
+}
+
+QString QAccessibleComboBox::actionText(int action, Text t, int child) const
+{
+ QString text;
+ if (child == 2 && t == Name && (action == DefaultAction || action == Press))
+ text = comboBox()->view()->isVisible() ? QComboBox::tr("Close") : QComboBox::tr("Open");
+ return text;
+}
+#endif // QT_NO_COMBOBOX
+
+static inline void removeInvisibleWidgetsFromList(QWidgetList *list)
+{
+ if (!list || list->isEmpty())
+ return;
+
+ for (int i = 0; i < list->count(); ++i) {
+ QWidget *widget = list->at(i);
+ if (!widget->isVisible())
+ list->removeAt(i);
+ }
+}
+
+#ifndef QT_NO_SCROLLAREA
+// ======================= QAccessibleAbstractScrollArea =======================
+QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget)
+ : QAccessibleWidgetEx(widget, Client)
+{
+ Q_ASSERT(qobject_cast<QAbstractScrollArea *>(widget));
+}
+
+QString QAccessibleAbstractScrollArea::text(Text textType, int child) const
+{
+ if (child == Self)
+ return QAccessibleWidgetEx::text(textType, 0);
+ QWidgetList children = accessibleChildren();
+ if (child < 1 || child > children.count())
+ return QString();
+ QAccessibleInterface *childInterface = queryAccessibleInterface(children.at(child - 1));
+ if (!childInterface)
+ return QString();
+ QString string = childInterface->text(textType, 0);
+ delete childInterface;
+ return string;
+}
+
+void QAccessibleAbstractScrollArea::setText(Text textType, int child, const QString &text)
+{
+ if (text.isEmpty())
+ return;
+ if (child == 0) {
+ QAccessibleWidgetEx::setText(textType, 0, text);
+ return;
+ }
+ QWidgetList children = accessibleChildren();
+ if (child < 1 || child > children.count())
+ return;
+ QAccessibleInterface *childInterface = queryAccessibleInterface(children.at(child - 1));
+ if (!childInterface)
+ return;
+ childInterface->setText(textType, 0, text);
+ delete childInterface;
+}
+
+QAccessible::State QAccessibleAbstractScrollArea::state(int child) const
+{
+ if (child == Self)
+ return QAccessibleWidgetEx::state(child);
+ QWidgetList children = accessibleChildren();
+ if (child < 1 || child > children.count())
+ return QAccessibleWidgetEx::state(Self);
+ QAccessibleInterface *childInterface = queryAccessibleInterface(children.at(child - 1));
+ if (!childInterface)
+ return QAccessibleWidgetEx::state(Self);
+ QAccessible::State returnState = childInterface->state(0);
+ delete childInterface;
+ return returnState;
+}
+
+QVariant QAccessibleAbstractScrollArea::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+int QAccessibleAbstractScrollArea::childCount() const
+{
+ return accessibleChildren().count();
+}
+
+int QAccessibleAbstractScrollArea::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object())
+ return -1;
+ int index = accessibleChildren().indexOf(qobject_cast<QWidget *>(child->object()));
+ if (index >= 0)
+ return ++index;
+ return -1;
+}
+
+bool QAccessibleAbstractScrollArea::isValid() const
+{
+ return (QAccessibleWidgetEx::isValid() && abstractScrollArea() && abstractScrollArea()->viewport());
+}
+
+int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ if (!target)
+ return -1;
+
+ *target = 0;
+
+ QWidget *targetWidget = 0;
+ QWidget *entryWidget = 0;
+
+ if (relation == Child ||
+ relation == Left || relation == Up || relation == Right || relation == Down) {
+ QWidgetList children = accessibleChildren();
+ if (entry < 0 || entry > children.count())
+ return -1;
+
+ if (entry == Self)
+ entryWidget = abstractScrollArea();
+ else
+ entryWidget = children.at(entry - 1);
+ AbstractScrollAreaElement entryElement = elementType(entryWidget);
+
+ // Not one of the most beautiful switches I've ever seen, but I believe it has
+ // to be like this since each case need special handling.
+ // It might be possible to make it more general, but I'll leave that as an exercise
+ // to the reader. :-)
+ switch (relation) {
+ case Child:
+ if (entry > 0)
+ targetWidget = children.at(entry - 1);
+ break;
+ case Left:
+ if (entry < 1)
+ break;
+ switch (entryElement) {
+ case Viewport:
+ if (!isLeftToRight())
+ targetWidget = abstractScrollArea()->verticalScrollBar();
+ break;
+ case HorizontalContainer:
+ if (!isLeftToRight())
+ targetWidget = abstractScrollArea()->cornerWidget();
+ break;
+ case VerticalContainer:
+ if (isLeftToRight())
+ targetWidget = abstractScrollArea()->viewport();
+ break;
+ case CornerWidget:
+ if (isLeftToRight())
+ targetWidget = abstractScrollArea()->horizontalScrollBar();
+ break;
+ default:
+ break;
+ }
+ break;
+ case Right:
+ if (entry < 1)
+ break;
+ switch (entryElement) {
+ case Viewport:
+ if (isLeftToRight())
+ targetWidget = abstractScrollArea()->verticalScrollBar();
+ break;
+ case HorizontalContainer:
+ targetWidget = abstractScrollArea()->cornerWidget();
+ break;
+ case VerticalContainer:
+ if (!isLeftToRight())
+ targetWidget = abstractScrollArea()->viewport();
+ break;
+ case CornerWidget:
+ if (!isLeftToRight())
+ targetWidget = abstractScrollArea()->horizontalScrollBar();
+ break;
+ default:
+ break;
+ }
+ break;
+ case Up:
+ if (entry < 1)
+ break;
+ switch (entryElement) {
+ case HorizontalContainer:
+ targetWidget = abstractScrollArea()->viewport();
+ break;
+ case CornerWidget:
+ targetWidget = abstractScrollArea()->verticalScrollBar();
+ break;
+ default:
+ break;
+ }
+ break;
+ case Down:
+ if (entry < 1)
+ break;
+ switch (entryElement) {
+ case Viewport:
+ targetWidget = abstractScrollArea()->horizontalScrollBar();
+ break;
+ case VerticalContainer:
+ targetWidget = abstractScrollArea()->cornerWidget();
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+
+ if (qobject_cast<const QScrollBar *>(targetWidget))
+ targetWidget = targetWidget->parentWidget();
+ *target = QAccessible::queryAccessibleInterface(targetWidget);
+ return *target ? 0: -1;
+}
+
+QRect QAccessibleAbstractScrollArea::rect(int child) const
+{
+ if (!abstractScrollArea()->isVisible())
+ return QRect();
+ if (child == Self)
+ return QAccessibleWidgetEx::rect(child);
+ QWidgetList children = accessibleChildren();
+ if (child < 1 || child > children.count())
+ return QRect();
+ const QWidget *childWidget = children.at(child - 1);
+ if (!childWidget->isVisible())
+ return QRect();
+ return QRect(childWidget->mapToGlobal(QPoint(0, 0)), childWidget->size());
+}
+
+int QAccessibleAbstractScrollArea::childAt(int x, int y) const
+{
+ if (!abstractScrollArea()->isVisible())
+ return -1;
+#if 0
+ const QRect globalSelfGeometry = rect(Self);
+ if (!globalSelfGeometry.isValid() || !globalSelfGeometry.contains(QPoint(x, y)))
+ return -1;
+ const QWidgetList children = accessibleChildren();
+ for (int i = 0; i < children.count(); ++i) {
+ const QWidget *child = children.at(i);
+ const QRect globalChildGeometry = QRect(child->mapToGlobal(QPoint(0, 0)), child->size());
+ if (globalChildGeometry.contains(QPoint(x, y))) {
+ return ++i;
+ }
+ }
+ return 0;
+#else
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(x, y))
+ return i;
+ }
+ return -1;
+#endif
+}
+
+QAbstractScrollArea *QAccessibleAbstractScrollArea::abstractScrollArea() const
+{
+ return static_cast<QAbstractScrollArea *>(object());
+}
+
+QWidgetList QAccessibleAbstractScrollArea::accessibleChildren() const
+{
+ QWidgetList children;
+
+ // Viewport.
+ QWidget * viewport = abstractScrollArea()->viewport();
+ if (viewport)
+ children.append(viewport);
+
+ // Horizontal scrollBar container.
+ QScrollBar *horizontalScrollBar = abstractScrollArea()->horizontalScrollBar();
+ if (horizontalScrollBar && horizontalScrollBar->isVisible()) {
+ children.append(horizontalScrollBar->parentWidget());
+ }
+
+ // Vertical scrollBar container.
+ QScrollBar *verticalScrollBar = abstractScrollArea()->verticalScrollBar();
+ if (verticalScrollBar && verticalScrollBar->isVisible()) {
+ children.append(verticalScrollBar->parentWidget());
+ }
+
+ // CornerWidget.
+ QWidget *cornerWidget = abstractScrollArea()->cornerWidget();
+ if (cornerWidget && cornerWidget->isVisible())
+ children.append(cornerWidget);
+
+ return children;
+}
+
+QAccessibleAbstractScrollArea::AbstractScrollAreaElement
+QAccessibleAbstractScrollArea::elementType(QWidget *widget) const
+{
+ if (!widget)
+ return Undefined;
+
+ if (widget == abstractScrollArea())
+ return Self;
+ if (widget == abstractScrollArea()->viewport())
+ return Viewport;
+ if (widget->objectName() == QLatin1String("qt_scrollarea_hcontainer"))
+ return HorizontalContainer;
+ if (widget->objectName() == QLatin1String("qt_scrollarea_vcontainer"))
+ return VerticalContainer;
+ if (widget == abstractScrollArea()->cornerWidget())
+ return CornerWidget;
+
+ return Undefined;
+}
+
+bool QAccessibleAbstractScrollArea::isLeftToRight() const
+{
+ return abstractScrollArea()->isLeftToRight();
+}
+
+// ======================= QAccessibleScrollArea ===========================
+QAccessibleScrollArea::QAccessibleScrollArea(QWidget *widget)
+ : QAccessibleAbstractScrollArea(widget)
+{
+ Q_ASSERT(qobject_cast<QScrollArea *>(widget));
+}
+#endif // QT_NO_SCROLLAREA
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h
new file mode 100644
index 0000000000..b5ba13941d
--- /dev/null
+++ b/src/plugins/accessible/widgets/complexwidgets.h
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPLEXWIDGETS_H
+#define COMPLEXWIDGETS_H
+
+#include <QtCore/qpointer.h>
+#include <QtGui/qaccessiblewidget.h>
+#include <QtGui/qabstractitemview.h>
+#include <QtGui/qaccessible2.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAbstractButton;
+class QHeaderView;
+class QTabBar;
+class QComboBox;
+class QTitleBar;
+class QAbstractScrollArea;
+class QScrollArea;
+
+#ifndef QT_NO_SCROLLAREA
+class QAccessibleAbstractScrollArea : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleAbstractScrollArea(QWidget *widget);
+
+ enum AbstractScrollAreaElement {
+ Self = 0,
+ Viewport,
+ HorizontalContainer,
+ VerticalContainer,
+ CornerWidget,
+ Undefined
+ };
+
+ QString text(Text textType, int child) const;
+ void setText(Text textType, int child, const QString &text);
+ State state(int child) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ bool isValid() const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+ QRect rect(int child) const;
+ int childAt(int x, int y) const;
+
+//protected:
+ QAbstractScrollArea *abstractScrollArea() const;
+
+private:
+ QWidgetList accessibleChildren() const;
+ AbstractScrollAreaElement elementType(QWidget *widget) const;
+ bool isLeftToRight() const;
+};
+
+class QAccessibleScrollArea : public QAccessibleAbstractScrollArea
+{
+public:
+ explicit QAccessibleScrollArea(QWidget *widget);
+};
+
+#endif // QT_NO_SCROLLAREA
+
+#ifndef QT_NO_ITEMVIEWS
+class QAccessibleHeader : public QAccessibleWidgetEx
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleHeader(QWidget *w);
+
+ int childCount() const;
+
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+protected:
+ QHeaderView *header() const;
+};
+
+class QAccessibleItemRow: public QAccessibleInterface
+{
+ friend class QAccessibleItemView;
+public:
+ QAccessibleItemRow(QAbstractItemView *view, const QModelIndex &index = QModelIndex(), bool isHeader = false);
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ void setText(Text t, int child, const QString &text);
+ bool isValid() const;
+ QObject *object() const;
+ Role role(int child) const;
+ State state(int child) const;
+
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *) const;
+ QList<QModelIndex> children() const;
+
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+ int childAt(int x, int y) const;
+ int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
+
+ int userActionCount(int child) const;
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList &params = QVariantList());
+
+ QModelIndex childIndex(int child) const;
+
+ QHeaderView *horizontalHeader() const; //used by QAccessibleItemView
+private:
+ static QAbstractItemView::CursorAction toCursorAction(Relation rel);
+ int logicalFromChild(QHeaderView *header, int child) const;
+ int treeLevel() const;
+ QHeaderView *verticalHeader() const;
+ QString text_helper(int child) const;
+
+ QPersistentModelIndex row;
+ QPointer<QAbstractItemView> view;
+ bool m_header;
+};
+
+class QAccessibleItemView: public QAccessibleAbstractScrollArea, public QAccessibleTableInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleItemView(QWidget *w);
+
+ QObject *object() const;
+ Role role(int child) const;
+ State state(int child) const;
+ QRect rect(int child) const;
+ int childAt(int x, int y) const;
+ int childCount() const;
+ QString text(Text t, int child) const;
+ void setText(Text t, int child, const QString &text);
+ int indexOfChild(const QAccessibleInterface *iface) const;
+
+ QModelIndex childIndex(int child) const;
+ int entryFromIndex(const QModelIndex &index) const;
+ bool isValid() const;
+ int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
+
+ QAccessibleInterface *accessibleAt(int row, int column);
+ QAccessibleInterface *caption();
+ int childIndex(int rowIndex, int columnIndex);
+ QString columnDescription(int column);
+ int columnSpan(int row, int column);
+ QAccessibleInterface *columnHeader();
+ int columnIndex(int childIndex);
+ int columnCount();
+ int rowCount();
+ int selectedColumnCount();
+ int selectedRowCount();
+ QString rowDescription(int row);
+ int rowSpan(int row, int column);
+ QAccessibleInterface *rowHeader();
+ int rowIndex(int childIndex);
+ int selectedRows(int maxRows, QList<int> *rows);
+ int selectedColumns(int maxColumns, QList<int> *columns);
+ QAccessibleInterface *summary();
+ bool isColumnSelected(int column);
+ bool isRowSelected(int row);
+ bool isSelected(int row, int column);
+ void selectRow(int row);
+ void selectColumn(int column);
+ void unselectRow(int row);
+ void unselectColumn(int column);
+ void cellAtIndex(int index, int *row, int *column, int *rowSpan,
+ int *columnSpan, bool *isSelected);
+
+ QHeaderView *horizontalHeader() const;
+ QHeaderView *verticalHeader() const;
+ bool isValidChildRole(QAccessible::Role role) const;
+
+protected:
+ QAbstractItemView *itemView() const;
+ QModelIndex index(int row, int column) const;
+
+private:
+ inline bool atViewport() const {
+ return atVP;
+ };
+ QAccessible::Role expectedRoleOfChildren() const;
+
+ bool atVP;
+};
+
+#endif
+
+#ifndef QT_NO_TABBAR
+class QAccessibleTabBar : public QAccessibleWidgetEx
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleTabBar(QWidget *w);
+
+ int childCount() const;
+
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+ bool doAction(int action, int child, const QVariantList &params);
+ bool setSelected(int child, bool on, bool extend);
+ QVector<int> selection() const;
+
+protected:
+ QTabBar *tabBar() const;
+
+private:
+ QAbstractButton *button(int child) const;
+};
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_COMBOBOX
+class QAccessibleComboBox : public QAccessibleWidgetEx
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleComboBox(QWidget *w);
+
+ enum ComboBoxElements {
+ ComboBoxSelf = 0,
+ CurrentText,
+ OpenList,
+ PopupList
+ };
+
+ int childCount() const;
+ int childAt(int x, int y) const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
+
+ QString text(Text t, int child) const;
+ QRect rect(int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+ bool doAction(int action, int child, const QVariantList &params);
+ QString actionText(int action, Text t, int child) const;
+
+protected:
+ QComboBox *comboBox() const;
+};
+#endif // QT_NO_COMBOBOX
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // COMPLEXWIDGETS_H
diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp
new file mode 100644
index 0000000000..c73702edad
--- /dev/null
+++ b/src/plugins/accessible/widgets/main.cpp
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblewidgets.h"
+#include "qaccessiblemenu.h"
+#include "simplewidgets.h"
+#include "rangecontrols.h"
+#include "complexwidgets.h"
+
+#include <qaccessibleplugin.h>
+#include <qplugin.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qvariant.h>
+#include <qaccessible.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+class AccessibleFactory : public QAccessiblePlugin
+{
+public:
+ AccessibleFactory();
+
+ QStringList keys() const;
+ QAccessibleInterface *create(const QString &classname, QObject *object);
+};
+
+AccessibleFactory::AccessibleFactory()
+{
+}
+
+QStringList AccessibleFactory::keys() const
+{
+ QStringList list;
+#ifndef QT_NO_LINEEDIT
+ list << QLatin1String("QLineEdit");
+#endif
+#ifndef QT_NO_COMBOBOX
+ list << QLatin1String("QComboBox");
+#endif
+#ifndef QT_NO_SPINBOX
+ list << QLatin1String("QAbstractSpinBox");
+ list << QLatin1String("QSpinBox");
+ list << QLatin1String("QDoubleSpinBox");
+#endif
+#ifndef QT_NO_SCROLLBAR
+ list << QLatin1String("QScrollBar");
+#endif
+#ifndef QT_NO_SLIDER
+ list << QLatin1String("QSlider");
+#endif
+ list << QLatin1String("QAbstractSlider");
+#ifndef QT_NO_TOOLBUTTON
+ list << QLatin1String("QToolButton");
+#endif
+ list << QLatin1String("QCheckBox");
+ list << QLatin1String("QRadioButton");
+ list << QLatin1String("QPushButton");
+ list << QLatin1String("QAbstractButton");
+ list << QLatin1String("QDialog");
+ list << QLatin1String("QMessageBox");
+ list << QLatin1String("QMainWindow");
+ list << QLatin1String("QLabel");
+ list << QLatin1String("QLCDNumber");
+ list << QLatin1String("QGroupBox");
+ list << QLatin1String("QStatusBar");
+ list << QLatin1String("QProgressBar");
+ list << QLatin1String("QMenuBar");
+ list << QLatin1String("Q3PopupMenu");
+ list << QLatin1String("QMenu");
+ list << QLatin1String("QHeaderView");
+ list << QLatin1String("QTabBar");
+ list << QLatin1String("QToolBar");
+ list << QLatin1String("QWorkspaceChild");
+ list << QLatin1String("QSizeGrip");
+ list << QLatin1String("QAbstractItemView");
+ list << QLatin1String("QWidget");
+#ifndef QT_NO_SPLITTER
+ list << QLatin1String("QSplitter");
+ list << QLatin1String("QSplitterHandle");
+#endif
+#ifndef QT_NO_TEXTEDIT
+ list << QLatin1String("QTextEdit");
+#endif
+ list << QLatin1String("QTipLabel");
+ list << QLatin1String("QFrame");
+ list << QLatin1String("QStackedWidget");
+ list << QLatin1String("QToolBox");
+ list << QLatin1String("QMdiArea");
+ list << QLatin1String("QMdiSubWindow");
+ list << QLatin1String("QWorkspace");
+ list << QLatin1String("QDialogButtonBox");
+#ifndef QT_NO_DIAL
+ list << QLatin1String("QDial");
+#endif
+#ifndef QT_NO_RUBBERBAND
+ list << QLatin1String("QRubberBand");
+#endif
+#ifndef QT_NO_TEXTBROWSER
+ list << QLatin1String("QTextBrowser");
+#endif
+#ifndef QT_NO_SCROLLAREA
+ list << QLatin1String("QAbstractScrollArea");
+ list << QLatin1String("QScrollArea");
+#endif
+#ifndef QT_NO_CALENDARWIDGET
+ list << QLatin1String("QCalendarWidget");
+#endif
+
+#ifndef QT_NO_DOCKWIDGET
+ list << QLatin1String("QDockWidget");
+#endif
+ return list;
+}
+
+QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObject *object)
+{
+ QAccessibleInterface *iface = 0;
+ if (!object || !object->isWidgetType())
+ return iface;
+ QWidget *widget = static_cast<QWidget*>(object);
+
+ if (false) {
+#ifndef QT_NO_LINEEDIT
+ } else if (classname == QLatin1String("QLineEdit")) {
+ iface = new QAccessibleLineEdit(widget);
+#endif
+#ifndef QT_NO_COMBOBOX
+ } else if (classname == QLatin1String("QComboBox")) {
+ iface = new QAccessibleComboBox(widget);
+#endif
+#ifndef QT_NO_SPINBOX
+ } else if (classname == QLatin1String("QAbstractSpinBox")) {
+ iface = new QAccessibleAbstractSpinBox(widget);
+ } else if (classname == QLatin1String("QSpinBox")) {
+ iface = new QAccessibleSpinBox(widget);
+ } else if (classname == QLatin1String("QDoubleSpinBox")) {
+ iface = new QAccessibleDoubleSpinBox(widget);
+#endif
+#ifndef QT_NO_SCROLLBAR
+ } else if (classname == QLatin1String("QScrollBar")) {
+ iface = new QAccessibleScrollBar(widget);
+#endif
+ } else if (classname == QLatin1String("QAbstractSlider")) {
+ iface = new QAccessibleAbstractSlider(widget);
+#ifndef QT_NO_SLIDER
+ } else if (classname == QLatin1String("QSlider")) {
+ iface = new QAccessibleSlider(widget);
+#endif
+#ifndef QT_NO_TOOLBUTTON
+ } else if (classname == QLatin1String("QToolButton")) {
+ Role role = NoRole;
+#ifndef QT_NO_MENU
+ QToolButton *tb = qobject_cast<QToolButton*>(widget);
+ if (!tb->menu())
+ role = tb->isCheckable() ? CheckBox : PushButton;
+ else if (!tb->popupMode() != QToolButton::DelayedPopup)
+ role = ButtonDropDown;
+ else
+#endif
+ role = ButtonMenu;
+ iface = new QAccessibleToolButton(widget, role);
+#endif // QT_NO_TOOLBUTTON
+ } else if (classname == QLatin1String("QCheckBox")) {
+ iface = new QAccessibleButton(widget, CheckBox);
+ } else if (classname == QLatin1String("QRadioButton")) {
+ iface = new QAccessibleButton(widget, RadioButton);
+ } else if (classname == QLatin1String("QPushButton")) {
+ Role role = NoRole;
+ QPushButton *pb = qobject_cast<QPushButton*>(widget);
+#ifndef QT_NO_MENU
+ if (pb->menu())
+ role = ButtonMenu;
+ else
+#endif
+ if (pb->isCheckable())
+ role = CheckBox;
+ else
+ role = PushButton;
+ iface = new QAccessibleButton(widget, role);
+ } else if (classname == QLatin1String("QAbstractButton")) {
+ iface = new QAccessibleButton(widget, PushButton);
+ } else if (classname == QLatin1String("QDialog")) {
+ iface = new QAccessibleWidgetEx(widget, Dialog);
+ } else if (classname == QLatin1String("QMessageBox")) {
+ iface = new QAccessibleWidgetEx(widget, AlertMessage);
+#ifndef QT_NO_MAINWINDOW
+ } else if (classname == QLatin1String("QMainWindow")) {
+ iface = new QAccessibleMainWindow(widget);
+#endif
+ } else if (classname == QLatin1String("QLabel") || classname == QLatin1String("QLCDNumber")) {
+ iface = new QAccessibleDisplay(widget);
+ } else if (classname == QLatin1String("QGroupBox")) {
+ iface = new QAccessibleDisplay(widget, Grouping);
+ } else if (classname == QLatin1String("QStatusBar")) {
+ iface = new QAccessibleWidgetEx(widget, StatusBar);
+#ifndef QT_NO_PROGRESSBAR
+ } else if (classname == QLatin1String("QProgressBar")) {
+ iface = new QAccessibleProgressBar(widget);
+#endif
+ } else if (classname == QLatin1String("QToolBar")) {
+ iface = new QAccessibleWidgetEx(widget, ToolBar, widget->windowTitle());
+#ifndef QT_NO_MENUBAR
+ } else if (classname == QLatin1String("QMenuBar")) {
+ iface = new QAccessibleMenuBar(widget);
+#endif
+#ifndef QT_NO_MENU
+ } else if (classname == QLatin1String("QMenu")) {
+ iface = new QAccessibleMenu(widget);
+ } else if (classname == QLatin1String("Q3PopupMenu")) {
+ iface = new QAccessibleMenu(widget);
+#endif
+#ifndef QT_NO_ITEMVIEWS
+ } else if (classname == QLatin1String("QHeaderView")) {
+ iface = new QAccessibleHeader(widget);
+ } else if (classname == QLatin1String("QAbstractItemView")) {
+ iface = new QAccessibleItemView(widget);
+ } else if (classname == QLatin1String("QWidget")
+ && widget->objectName() == QLatin1String("qt_scrollarea_viewport")
+ && qobject_cast<QAbstractItemView*>(widget->parentWidget())) {
+ iface = new QAccessibleItemView(widget);
+#endif
+#ifndef QT_NO_TABBAR
+ } else if (classname == QLatin1String("QTabBar")) {
+ iface = new QAccessibleTabBar(widget);
+#endif
+ } else if (classname == QLatin1String("QWorkspaceChild")) {
+ iface = new QAccessibleWidgetEx(widget, Window);
+ } else if (classname == QLatin1String("QSizeGrip")) {
+ iface = new QAccessibleWidgetEx(widget, Grip);
+#ifndef QT_NO_SPLITTER
+ } else if (classname == QLatin1String("QSplitter")) {
+ iface = new QAccessibleWidgetEx(widget, Splitter);
+ } else if (classname == QLatin1String("QSplitterHandle")) {
+ iface = new QAccessibleWidgetEx(widget, Grip);
+#endif
+#ifndef QT_NO_TEXTEDIT
+ } else if (classname == QLatin1String("QTextEdit")) {
+ iface = new QAccessibleTextEdit(widget);
+#endif
+ } else if (classname == QLatin1String("QTipLabel")) {
+ iface = new QAccessibleDisplay(widget, ToolTip);
+ } else if (classname == QLatin1String("QFrame")) {
+ iface = new QAccessibleWidget(widget, Border);
+#ifndef QT_NO_STACKEDWIDGET
+ } else if (classname == QLatin1String("QStackedWidget")) {
+ iface = new QAccessibleStackedWidget(widget);
+#endif
+#ifndef QT_NO_TOOLBOX
+ } else if (classname == QLatin1String("QToolBox")) {
+ iface = new QAccessibleToolBox(widget);
+#endif
+#ifndef QT_NO_MDIAREA
+ } else if (classname == QLatin1String("QMdiArea")) {
+ iface = new QAccessibleMdiArea(widget);
+ } else if (classname == QLatin1String("QMdiSubWindow")) {
+ iface = new QAccessibleMdiSubWindow(widget);
+#endif
+#ifndef QT_NO_WORKSPACE
+ } else if (classname == QLatin1String("QWorkspace")) {
+ iface = new QAccessibleWorkspace(widget);
+#endif
+ } else if (classname == QLatin1String("QDialogButtonBox")) {
+ iface = new QAccessibleDialogButtonBox(widget);
+#ifndef QT_NO_DIAL
+ } else if (classname == QLatin1String("QDial")) {
+ iface = new QAccessibleDial(widget);
+#endif
+#ifndef QT_NO_RUBBERBAND
+ } else if (classname == QLatin1String("QRubberBand")) {
+ iface = new QAccessibleWidgetEx(widget, QAccessible::Border);
+#endif
+#ifndef QT_NO_TEXTBROWSER
+ } else if (classname == QLatin1String("QTextBrowser")) {
+ iface = new QAccessibleTextBrowser(widget);
+#endif
+#ifndef QT_NO_SCROLLAREA
+ } else if (classname == QLatin1String("QAbstractScrollArea")) {
+ iface = new QAccessibleAbstractScrollArea(widget);
+ } else if (classname == QLatin1String("QScrollArea")) {
+ iface = new QAccessibleScrollArea(widget);
+#endif
+#ifndef QT_NO_CALENDARWIDGET
+ } else if (classname == QLatin1String("QCalendarWidget")) {
+ iface = new QAccessibleCalendarWidget(widget);
+#endif
+#ifndef QT_NO_DOCKWIDGET
+ } else if (classname == QLatin1String("QDockWidget")) {
+ iface = new QAccessibleDockWidget(widget);
+#endif
+ }
+
+ return iface;
+}
+
+Q_EXPORT_STATIC_PLUGIN(AccessibleFactory)
+Q_EXPORT_PLUGIN2(qtaccessiblewidgets, AccessibleFactory)
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
new file mode 100644
index 0000000000..6d8a358d5c
--- /dev/null
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
@@ -0,0 +1,678 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblemenu.h"
+
+#include <qmenu.h>
+#include <qmenubar.h>
+#include <QtGui/QAction>
+#include <qstyle.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_MENU
+
+QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
+QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
+
+QAccessibleMenu::QAccessibleMenu(QWidget *w)
+: QAccessibleWidgetEx(w)
+{
+ Q_ASSERT(menu());
+}
+
+QMenu *QAccessibleMenu::menu() const
+{
+ return qobject_cast<QMenu*>(object());
+}
+
+int QAccessibleMenu::childCount() const
+{
+ return menu()->actions().count();
+}
+
+QRect QAccessibleMenu::rect(int child) const
+{
+ if (!child || child > childCount())
+ return QAccessibleWidgetEx::rect(child);
+
+ QRect r = menu()->actionGeometry(menu()->actions()[child - 1]);
+ QPoint tlp = menu()->mapToGlobal(QPoint(0,0));
+
+ return QRect(tlp.x() + r.x(), tlp.y() + r.y(), r.width(), r.height());
+}
+
+int QAccessibleMenu::childAt(int x, int y) const
+{
+ QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
+ if(act && act->isSeparator())
+ act = 0;
+ return menu()->actions().indexOf(act) + 1;
+}
+
+QString QAccessibleMenu::text(Text t, int child) const
+{
+ QString tx = QAccessibleWidgetEx::text(t, child);
+ if (tx.size())
+ return tx;
+
+ switch (t) {
+ case Name:
+ if (!child)
+ return menu()->windowTitle();
+ return qt_accStripAmp(menu()->actions().at(child-1)->text());
+ case Help:
+ return child ? menu()->actions().at(child-1)->whatsThis() : tx;
+#ifndef QT_NO_SHORTCUT
+ case Accelerator:
+ return child ? static_cast<QString>(menu()->actions().at(child-1)->shortcut()) : tx;
+#endif
+ default:
+ break;
+ }
+ return tx;
+}
+
+QAccessible::Role QAccessibleMenu::role(int child) const
+{
+ if (!child)
+ return PopupMenu;
+
+ QAction *action = menu()->actions()[child-1];
+ if (action && action->isSeparator())
+ return Separator;
+ return MenuItem;
+}
+
+QAccessible::State QAccessibleMenu::state(int child) const
+{
+ State s = QAccessibleWidgetEx::state(child);
+ if (!child)
+ return s;
+
+ QAction *action = menu()->actions()[child-1];
+ if (!action)
+ return s;
+
+ if (menu()->style()->styleHint(QStyle::SH_Menu_MouseTracking))
+ s |= HotTracked;
+ if (action->isSeparator() || !action->isEnabled())
+ s |= Unavailable;
+ if (action->isChecked())
+ s |= Checked;
+ if (menu()->activeAction() == action)
+ s |= Focused;
+
+ return s;
+}
+
+QString QAccessibleMenu::actionText(int action, QAccessible::Text text, int child) const
+{
+ if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) {
+ QAction *a = menu()->actions().value(child-1, 0);
+ if (!a || a->isSeparator())
+ return QString();
+ if (a->menu()) {
+ if (a->menu()->isVisible())
+ return QMenu::tr("Close");
+ return QMenu::tr("Open");
+ }
+ return QMenu::tr("Execute");
+ }
+
+ return QAccessibleWidgetEx::actionText(action, text, child);
+}
+
+bool QAccessibleMenu::doAction(int act, int child, const QVariantList &)
+{
+ if (!child || act != QAccessible::DefaultAction)
+ return false;
+
+ QAction *action = menu()->actions().value(child-1, 0);
+ if (!action || !action->isEnabled())
+ return false;
+
+ if (action->menu() && action->menu()->isVisible())
+ action->menu()->hide();
+ else
+ menu()->setActiveAction(action);
+ return true;
+}
+
+int QAccessibleMenu::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ int ret = -1;
+ if (entry < 0) {
+ *target = 0;
+ return ret;
+ }
+
+ if (relation == Self || entry == 0) {
+ *target = new QAccessibleMenu(menu());
+ return 0;
+ }
+
+ switch (relation) {
+ case Child:
+ if (entry <= childCount()) {
+ *target = new QAccessibleMenuItem(menu(), menu()->actions().at( entry - 1 ));
+ ret = 0;
+ }
+ break;
+ case Ancestor: {
+ QAccessibleInterface *iface;
+ QWidget *parent = menu()->parentWidget();
+ if (qobject_cast<QMenu*>(parent) || qobject_cast<QMenuBar*>(parent)) {
+ iface = new QAccessibleMenuItem(parent, menu()->menuAction());
+ if (entry == 1) {
+ *target = iface;
+ ret = 0;
+ } else {
+ ret = iface->navigate(Ancestor, entry - 1, target);
+ delete iface;
+ }
+ } else {
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+ break;}
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+
+
+ if (ret == -1)
+ *target = 0;
+
+ return ret;
+
+}
+
+int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child ) const
+{
+ int index = -1;
+ Role r = child->role(0);
+ if ((r == MenuItem || r == Separator) && menu()) {
+ index = menu()->actions().indexOf(qobject_cast<QAction*>(child->object()));
+ if (index != -1)
+ ++index;
+ }
+ return index;
+}
+
+#ifndef QT_NO_MENUBAR
+QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
+: QAccessibleWidgetEx(w)
+{
+ Q_ASSERT(menuBar());
+}
+
+QMenuBar *QAccessibleMenuBar::menuBar() const
+{
+ return qobject_cast<QMenuBar*>(object());
+}
+
+int QAccessibleMenuBar::childCount() const
+{
+ return menuBar()->actions().count();
+}
+
+QRect QAccessibleMenuBar::rect(int child) const
+{
+ if (!child)
+ return QAccessibleWidgetEx::rect(child);
+
+ QRect r = menuBar()->actionGeometry(menuBar()->actions()[child - 1]);
+ QPoint tlp = menuBar()->mapToGlobal(QPoint(0,0));
+ return QRect(tlp.x() + r.x(), tlp.y() + r.y(), r.width(), r.height());
+}
+
+int QAccessibleMenuBar::childAt(int x, int y) const
+{
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(x,y))
+ return i;
+ }
+ return -1;
+}
+
+int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ int ret = -1;
+ if (entry < 0) {
+ *target = 0;
+ return ret;
+ }
+
+ if (relation == Self || entry == 0) {
+ *target = new QAccessibleMenuBar(menuBar());
+ return 0;
+ }
+
+ switch (relation) {
+ case Child:
+ if (entry <= childCount()) {
+ *target = new QAccessibleMenuItem(menuBar(), menuBar()->actions().at( entry - 1 ));
+ ret = 0;
+ }
+ break;
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+
+
+ if (ret == -1)
+ *target = 0;
+
+ return ret;
+}
+
+int QAccessibleMenuBar::indexOfChild( const QAccessibleInterface *child ) const
+{
+ int index = -1;
+ Role r = child->role(0);
+ if ((r == MenuItem || r == Separator) && menuBar()) {
+ index = menuBar()->actions().indexOf(qobject_cast<QAction*>(child->object()));
+ if (index != -1)
+ ++index;
+ }
+ return index;
+}
+
+QString QAccessibleMenuBar::text(Text t, int child) const
+{
+ QString str;
+
+ if (child) {
+ if (QAction *action = menuBar()->actions().value(child - 1, 0)) {
+ switch (t) {
+ case Name:
+ return qt_accStripAmp(action->text());
+ case Accelerator:
+ str = qt_accHotKey(action->text());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, child);
+ return str;
+}
+
+QAccessible::Role QAccessibleMenuBar::role(int child) const
+{
+ if (!child)
+ return MenuBar;
+
+ QAction *action = menuBar()->actions()[child-1];
+ if (action && action->isSeparator())
+ return Separator;
+ return MenuItem;
+}
+
+QAccessible::State QAccessibleMenuBar::state(int child) const
+{
+ State s = QAccessibleWidgetEx::state(child);
+ if (!child)
+ return s;
+
+ QAction *action = menuBar()->actions().value(child-1, 0);
+ if (!action)
+ return s;
+
+ if (menuBar()->style()->styleHint(QStyle::SH_Menu_MouseTracking))
+ s |= HotTracked;
+ if (action->isSeparator() || !action->isEnabled())
+ s |= Unavailable;
+ if (menuBar()->activeAction() == action)
+ s |= Focused;
+
+ return s;
+}
+
+QString QAccessibleMenuBar::actionText(int action, QAccessible::Text text, int child) const
+{
+ if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) {
+ QAction *a = menuBar()->actions().value(child-1, 0);
+ if (!a || a->isSeparator())
+ return QString();
+ if (a->menu()) {
+ if (a->menu()->isVisible())
+ return QMenu::tr("Close");
+ return QMenu::tr("Open");
+ }
+ return QMenu::tr("Execute");
+ }
+
+ return QAccessibleWidgetEx::actionText(action, text, child);
+}
+
+bool QAccessibleMenuBar::doAction(int act, int child, const QVariantList &)
+{
+ if (act != !child)
+ return false;
+
+ QAction *action = menuBar()->actions().value(child-1, 0);
+ if (!action || !action->isEnabled())
+ return false;
+ if (action->menu() && action->menu()->isVisible())
+ action->menu()->hide();
+ else
+ menuBar()->setActiveAction(action);
+ return true;
+}
+
+#endif // QT_NO_MENUBAR
+
+QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action) : m_action(action), m_owner(owner)
+{
+}
+
+
+QAccessibleMenuItem::~QAccessibleMenuItem()
+{}
+
+int QAccessibleMenuItem::childAt(int x, int y ) const
+{
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(x,y))
+ return i;
+ }
+ return -1;
+}
+
+int QAccessibleMenuItem::childCount() const
+{
+ return m_action->menu() ? 1 : 0;
+}
+
+QString QAccessibleMenuItem::actionText(int action, Text text, int child ) const
+{
+ if (text == Name && child == 0) {
+ switch (action) {
+ case Press:
+ case DefaultAction:
+ return QMenu::tr("Execute");
+ break;
+ default:
+ break;
+ }
+ }
+ return QString();
+}
+
+bool QAccessibleMenuItem::doAction(int action, int child, const QVariantList & /*params = QVariantList()*/ )
+{
+ if ((action == Press || action == DefaultAction) && child == 0) {
+ m_action->trigger();
+ return true;
+ }
+ return false;
+}
+
+int QAccessibleMenuItem::indexOfChild( const QAccessibleInterface * child ) const
+{
+ if (child->role(0) == PopupMenu && child->object() == m_action->menu())
+ return 1;
+
+ return -1;
+}
+
+bool QAccessibleMenuItem::isValid() const
+{
+ return m_action ? true : false;
+}
+
+int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleInterface ** target ) const
+{
+ int ret = -1;
+ if (entry < 0) {
+ *target = 0;
+ return ret;
+ }
+
+ if (relation == Self || entry == 0) {
+ *target = new QAccessibleMenuItem(owner(), action());
+ return 0;
+ }
+
+ switch (relation) {
+ case Child:
+ if (entry <= childCount()) {
+ *target = new QAccessibleMenu(action()->menu());
+ ret = 0;
+ }
+ break;
+
+ case Ancestor:{
+ QWidget *parent = owner();
+ QAccessibleInterface *ancestor = parent ? QAccessible::queryAccessibleInterface(parent) : 0;
+ if (ancestor) {
+ if (entry == 1) {
+ *target = ancestor;
+ ret = 0;
+ } else {
+ ret = ancestor->navigate(Ancestor, entry - 1, target);
+ delete ancestor;
+ }
+ }
+ break;}
+ case Up:
+ case Down:{
+ QAccessibleInterface *parent = 0;
+ int ent = navigate(Ancestor, 1, &parent);
+ if (ent == 0) {
+ int index = parent->indexOfChild(this);
+ if (index != -1) {
+ index += (relation == Down ? +1 : -1);
+ ret = parent->navigate(Child, index, target);
+ }
+ }
+ delete parent;
+ break;}
+ case Sibling: {
+ QAccessibleInterface *parent = 0;
+ int ent = navigate(Ancestor, 1, &parent);
+ if (ent == 0) {
+ ret = parent->navigate(Child, entry, target);
+ }
+ delete parent;
+ break;}
+ default:
+ break;
+
+ }
+ if (ret == -1)
+ *target = 0;
+ return ret;
+}
+
+QObject *QAccessibleMenuItem::object() const
+{
+ return m_action;
+}
+
+QRect QAccessibleMenuItem::rect (int child ) const
+{
+ QRect rect;
+ if (child == 0) {
+ QWidget *own = owner();
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
+ rect = menuBar->actionGeometry(m_action);
+ QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
+ rect = rect.translated(globalPos);
+ } else
+#endif // QT_NO_MENUBAR
+ if (QMenu *menu = qobject_cast<QMenu*>(own)) {
+ rect = menu->actionGeometry(m_action);
+ QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
+ rect = rect.translated(globalPos);
+ }
+ } else if (child == 1) {
+ QMenu *menu = m_action->menu();
+ if (menu) {
+ rect = menu->rect();
+ QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
+ rect = rect.translated(globalPos);
+ }
+ }
+ return rect;
+}
+
+QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const
+{
+ if (other->object() == owner()) {
+ return Child;
+ }
+ Q_UNUSED(child)
+ Q_UNUSED(other)
+ Q_UNUSED(otherChild)
+ // ###
+ return Unrelated;
+}
+
+QAccessible::Role QAccessibleMenuItem::role(int /*child*/ ) const
+{
+ return m_action->isSeparator() ? Separator :MenuItem;
+}
+
+void QAccessibleMenuItem::setText ( Text /*t*/, int /*child*/, const QString & /*text */)
+{
+
+}
+
+QAccessible::State QAccessibleMenuItem::state(int child ) const
+{
+ QAccessible::State s = Unavailable;
+
+ if (child == 0) {
+ s = Normal;
+ QWidget *own = owner();
+
+ if (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false) {
+ s |= Invisible;
+ }
+
+ if (QMenu *menu = qobject_cast<QMenu*>(own)) {
+ if (menu->activeAction() == m_action)
+ s |= Focused;
+#ifndef QT_NO_MENUBAR
+ } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
+ if (menuBar->activeAction() == m_action)
+ s |= Focused;
+#endif
+ }
+ if (own->style()->styleHint(QStyle::SH_Menu_MouseTracking))
+ s |= HotTracked;
+ if (m_action->isSeparator() || !m_action->isEnabled())
+ s |= Unavailable;
+ if (m_action->isChecked())
+ s |= Checked;
+ } else if (child == 1) {
+ QMenu *menu = m_action->menu();
+ if (menu) {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(menu);
+ s = iface->state(0);
+ delete iface;
+ }
+ }
+ return s;
+}
+
+QString QAccessibleMenuItem::text ( Text t, int child ) const
+{
+ QString str;
+ switch (t) {
+ case Name:
+ if (child == 0) {
+ str = m_action->text();
+ } else if (child == 1) {
+ QMenu *m = m_action->menu();
+ if (m)
+ str = m->title();
+ }
+ str = qt_accStripAmp(str);
+ break;
+ case Accelerator:
+ if (child == 0) {
+#ifndef QT_NO_SHORTCUT
+ QKeySequence key = m_action->shortcut();
+ if (!key.isEmpty()) {
+ str = key.toString();
+ } else
+#endif
+ {
+ str = qt_accHotKey(m_action->text());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+int QAccessibleMenuItem::userActionCount ( int /*child*/ ) const
+{
+ return 0;
+}
+
+
+QAction *QAccessibleMenuItem::action() const
+{
+ return m_action;
+}
+
+QWidget *QAccessibleMenuItem::owner() const
+{
+ return m_owner;
+}
+
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
+
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h
new file mode 100644
index 0000000000..7decca02c7
--- /dev/null
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEMENU_H
+#define QACCESSIBLEMENU_H
+
+#include <QtGui/qaccessiblewidget.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#ifndef QT_NO_MENU
+class QMenu;
+class QMenuBar;
+class QAction;
+
+class QAccessibleMenu : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleMenu(QWidget *w);
+
+ int childCount() const;
+ int childAt(int x, int y) const;
+
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+ int indexOfChild( const QAccessibleInterface *child ) const;
+
+ QString actionText(int action, QAccessible::Text text, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+
+protected:
+ QMenu *menu() const;
+};
+
+#ifndef QT_NO_MENUBAR
+class QAccessibleMenuBar : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleMenuBar(QWidget *w);
+
+ int childCount() const;
+ int childAt(int x, int y) const;
+
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+ int indexOfChild( const QAccessibleInterface *child ) const;
+
+ QString actionText(int action, QAccessible::Text text, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+
+protected:
+ QMenuBar *menuBar() const;
+};
+#endif // QT_NO_MENUBAR
+
+
+
+class QAccessibleMenuItem : public QAccessibleInterface
+{
+public:
+ explicit QAccessibleMenuItem(QWidget *owner, QAction *w);
+
+ virtual ~QAccessibleMenuItem();
+ virtual QString actionText ( int action, Text t, int child ) const;
+ virtual int childAt ( int x, int y ) const;
+ virtual int childCount () const;
+ virtual bool doAction ( int action, int child, const QVariantList & params = QVariantList() );
+ virtual int indexOfChild ( const QAccessibleInterface * child ) const;
+ virtual bool isValid () const;
+ virtual int navigate ( RelationFlag relation, int entry, QAccessibleInterface ** target ) const;
+ virtual QObject * object () const;
+ virtual QRect rect ( int child ) const;
+ virtual Relation relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const;
+ virtual Role role ( int child ) const;
+ virtual void setText ( Text t, int child, const QString & text );
+ virtual State state ( int child ) const;
+ virtual QString text ( Text t, int child ) const;
+ virtual int userActionCount ( int child ) const;
+
+ QWidget *owner() const;
+
+
+protected:
+ QAction *action() const;
+private:
+ QAction *m_action;
+ QWidget *m_owner; // can hold either QMenu or the QMenuBar that contains the action
+};
+
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+#endif // QT_NO_ACCESSIBILITY
+#endif // QACCESSIBLEMENU_H
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
new file mode 100644
index 0000000000..09b5015785
--- /dev/null
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -0,0 +1,1667 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblewidgets.h"
+#include "qabstracttextdocumentlayout.h"
+#include "qapplication.h"
+#include "qclipboard.h"
+#include "qtextedit.h"
+#include "private/qtextedit_p.h"
+#include "qtextdocument.h"
+#include "qtextobject.h"
+#include "qscrollbar.h"
+#include "qdebug.h"
+#include <QApplication>
+#include <QStackedWidget>
+#include <QToolBox>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QWorkspace>
+#include <QDialogButtonBox>
+#include <limits.h>
+#include <QRubberBand>
+#include <QTextBrowser>
+#include <QCalendarWidget>
+#include <QAbstractItemView>
+#include <QDockWidget>
+#include <QMainWindow>
+#include <QAbstractButton>
+#include <private/qdockwidget_p.h>
+#include <QtGui/QFocusFrame>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+using namespace QAccessible2;
+
+QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
+{
+ if (widget == 0)
+ return QList<QWidget*>();
+ QList<QObject*> list = widget->children();
+ QList<QWidget*> widgets;
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(list.at(i));
+ if (!w)
+ continue;
+ QString objectName = w->objectName();
+ if ((includeTopLevel || !w->isWindow())
+ && !qobject_cast<QFocusFrame*>(w)
+ && !qobject_cast<QMenu*>(w)
+ && objectName != QLatin1String("qt_rubberband")
+ && objectName != QLatin1String("qt_qmainwindow_extended_splitter")) {
+ widgets.append(w);
+ }
+ }
+ return widgets;
+}
+
+static inline int distance(QWidget *source, QWidget *target,
+ QAccessible::RelationFlag relation)
+{
+ if (!source || !target)
+ return -1;
+
+ int returnValue = -1;
+ switch (relation) {
+ case QAccessible::Up:
+ if (target->y() <= source->y())
+ returnValue = source->y() - target->y();
+ break;
+ case QAccessible::Down:
+ if (target->y() >= source->y() + source->height())
+ returnValue = target->y() - (source->y() + source->height());
+ break;
+ case QAccessible::Right:
+ if (target->x() >= source->x() + source->width())
+ returnValue = target->x() - (source->x() + source->width());
+ break;
+ case QAccessible::Left:
+ if (target->x() <= source->x())
+ returnValue = source->x() - target->x();
+ break;
+ default:
+ break;
+ }
+ return returnValue;
+}
+
+static inline QWidget *mdiAreaNavigate(QWidget *area,
+ QAccessible::RelationFlag relation, int entry)
+{
+#if defined(QT_NO_MDIAREA) && defined(QT_NO_WORKSPACE)
+ Q_UNUSED(area);
+#endif
+#ifndef QT_NO_MDIAREA
+ const QMdiArea *mdiArea = qobject_cast<QMdiArea *>(area);
+#endif
+#ifndef QT_NO_WORKSPACE
+ const QWorkspace *workspace = qobject_cast<QWorkspace *>(area);
+#endif
+ if (true
+#ifndef QT_NO_MDIAREA
+ && !mdiArea
+#endif
+#ifndef QT_NO_WORKSPACE
+ && !workspace
+#endif
+ )
+ return 0;
+
+ QWidgetList windows;
+#ifndef QT_NO_MDIAREA
+ if (mdiArea) {
+ foreach (QMdiSubWindow *window, mdiArea->subWindowList())
+ windows.append(window);
+ } else
+#endif
+ {
+#ifndef QT_NO_WORKSPACE
+ foreach (QWidget *window, workspace->windowList())
+ windows.append(window->parentWidget());
+#endif
+ }
+
+ if (windows.isEmpty() || entry < 1 || entry > windows.count())
+ return 0;
+
+ QWidget *source = windows.at(entry - 1);
+ QMap<int, QWidget *> candidates;
+ foreach (QWidget *window, windows) {
+ if (source == window)
+ continue;
+ int candidateDistance = distance(source, window, relation);
+ if (candidateDistance >= 0)
+ candidates.insert(candidateDistance, window);
+ }
+
+ int minimumDistance = INT_MAX;
+ QWidget *target = 0;
+ foreach (QWidget *candidate, candidates) {
+ switch (relation) {
+ case QAccessible::Up:
+ case QAccessible::Down:
+ if (qAbs(candidate->x() - source->x()) < minimumDistance) {
+ target = candidate;
+ minimumDistance = qAbs(candidate->x() - source->x());
+ }
+ break;
+ case QAccessible::Left:
+ case QAccessible::Right:
+ if (qAbs(candidate->y() - source->y()) < minimumDistance) {
+ target = candidate;
+ minimumDistance = qAbs(candidate->y() - source->y());
+ }
+ break;
+ default:
+ break;
+ }
+ if (minimumDistance == 0)
+ break;
+ }
+
+#ifndef QT_NO_WORKSPACE
+ if (workspace) {
+ foreach (QWidget *widget, workspace->windowList()) {
+ if (widget->parentWidget() == target)
+ target = widget;
+ }
+ }
+#endif
+ return target;
+}
+
+#ifndef QT_NO_TEXTEDIT
+
+/*!
+ \class QAccessibleTextEdit
+ \brief The QAccessibleTextEdit class implements the QAccessibleInterface for richtext editors.
+ \internal
+*/
+
+static QTextBlock qTextBlockAt(const QTextDocument *doc, int pos)
+{
+ Q_ASSERT(pos >= 0);
+
+ QTextBlock block = doc->begin();
+ int i = 0;
+ while (block.isValid() && i < pos) {
+ block = block.next();
+ ++i;
+ }
+ return block;
+}
+
+static int qTextBlockPosition(QTextBlock block)
+{
+ int child = 0;
+ while (block.isValid()) {
+ block = block.previous();
+ ++child;
+ }
+
+ return child;
+}
+
+/*!
+ \fn QAccessibleTextEdit::QAccessibleTextEdit(QWidget* widget)
+
+ Constructs a QAccessibleTextEdit object for a \a widget.
+*/
+QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o)
+: QAccessibleWidgetEx(o, EditableText)
+{
+ Q_ASSERT(widget()->inherits("QTextEdit"));
+ childOffset = QAccessibleWidgetEx::childCount();
+}
+
+/*! Returns the text edit. */
+QTextEdit *QAccessibleTextEdit::textEdit() const
+{
+ return static_cast<QTextEdit *>(widget());
+}
+
+QRect QAccessibleTextEdit::rect(int child) const
+{
+ if (child <= childOffset)
+ return QAccessibleWidgetEx::rect(child);
+
+ QTextEdit *edit = textEdit();
+ QTextBlock block = qTextBlockAt(edit->document(), child - childOffset - 1);
+ if (!block.isValid())
+ return QRect();
+
+ QRect rect = edit->document()->documentLayout()->blockBoundingRect(block).toRect();
+ rect.translate(-edit->horizontalScrollBar()->value(), -edit->verticalScrollBar()->value());
+
+ rect = edit->viewport()->rect().intersect(rect);
+ if (rect.isEmpty())
+ return QRect();
+
+ return rect.translated(edit->viewport()->mapToGlobal(QPoint(0, 0)));
+}
+
+int QAccessibleTextEdit::childAt(int x, int y) const
+{
+ QTextEdit *edit = textEdit();
+ if (!edit->isVisible())
+ return -1;
+
+ QPoint point = edit->viewport()->mapFromGlobal(QPoint(x, y));
+ QTextBlock block = edit->cursorForPosition(point).block();
+ if (block.isValid())
+ return qTextBlockPosition(block) + childOffset;
+
+ return QAccessibleWidgetEx::childAt(x, y);
+}
+
+/*! \reimp */
+QString QAccessibleTextEdit::text(Text t, int child) const
+{
+ if (t == Value) {
+ if (child > childOffset)
+ return qTextBlockAt(textEdit()->document(), child - childOffset - 1).text();
+ if (!child)
+ return textEdit()->toPlainText();
+ }
+
+ return QAccessibleWidgetEx::text(t, child);
+}
+
+/*! \reimp */
+void QAccessibleTextEdit::setText(Text t, int child, const QString &text)
+{
+ if (t != Value || (child > 0 && child <= childOffset)) {
+ QAccessibleWidgetEx::setText(t, child, text);
+ return;
+ }
+ if (textEdit()->isReadOnly())
+ return;
+
+ if (!child) {
+ textEdit()->setText(text);
+ return;
+ }
+ QTextBlock block = qTextBlockAt(textEdit()->document(), child - childOffset - 1);
+ if (!block.isValid())
+ return;
+
+ QTextCursor cursor(block);
+ cursor.select(QTextCursor::BlockUnderCursor);
+ cursor.insertText(text);
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleTextEdit::role(int child) const
+{
+ if (child > childOffset)
+ return EditableText;
+ return QAccessibleWidgetEx::role(child);
+}
+
+QVariant QAccessibleTextEdit::invokeMethodEx(QAccessible::Method method, int child,
+ const QVariantList &params)
+{
+ if (child)
+ return QVariant();
+
+ switch (method) {
+ case ListSupportedMethods: {
+ QSet<QAccessible::Method> set;
+ set << ListSupportedMethods << SetCursorPosition << GetCursorPosition;
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
+ }
+ case SetCursorPosition:
+ setCursorPosition(params.value(0).toInt());
+ return true;
+ case GetCursorPosition:
+ return textEdit()->textCursor().position();
+ default:
+ return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
+ }
+}
+
+int QAccessibleTextEdit::childCount() const
+{
+ return childOffset + textEdit()->document()->blockCount();
+}
+#endif // QT_NO_TEXTEDIT
+
+#ifndef QT_NO_STACKEDWIDGET
+// ======================= QAccessibleStackedWidget ======================
+QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget)
+ : QAccessibleWidgetEx(widget, LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QStackedWidget *>(widget));
+}
+
+QVariant QAccessibleStackedWidget::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+
+int QAccessibleStackedWidget::childAt(int x, int y) const
+{
+ if (!stackedWidget()->isVisible())
+ return -1;
+ QWidget *currentWidget = stackedWidget()->currentWidget();
+ if (!currentWidget)
+ return -1;
+ QPoint position = currentWidget->mapFromGlobal(QPoint(x, y));
+ if (currentWidget->rect().contains(position))
+ return 1;
+ return -1;
+}
+
+int QAccessibleStackedWidget::childCount() const
+{
+ return stackedWidget()->count();
+}
+
+int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || (stackedWidget()->currentWidget() != child->object()))
+ return -1;
+ return 1;
+}
+
+int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+
+ QObject *targetObject = 0;
+ switch (relation) {
+ case Child:
+ if (entry != 1)
+ return -1;
+ targetObject = stackedWidget()->currentWidget();
+ break;
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ return *target ? 0 : -1;
+}
+
+QStackedWidget *QAccessibleStackedWidget::stackedWidget() const
+{
+ return static_cast<QStackedWidget *>(object());
+}
+#endif // QT_NO_STACKEDWIDGET
+
+#ifndef QT_NO_TOOLBOX
+// ======================= QAccessibleToolBox ======================
+QAccessibleToolBox::QAccessibleToolBox(QWidget *widget)
+ : QAccessibleWidgetEx(widget, LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QToolBox *>(widget));
+}
+
+QString QAccessibleToolBox::text(Text textType, int child) const
+{
+ if (textType != Value || child <= 0 || child > toolBox()->count())
+ return QAccessibleWidgetEx::text(textType, child);
+ return toolBox()->itemText(child - 1);
+}
+
+void QAccessibleToolBox::setText(Text textType, int child, const QString &text)
+{
+ if (textType != Value || child <= 0 || child > toolBox()->count()) {
+ QAccessibleWidgetEx::setText(textType, child, text);
+ return;
+ }
+ toolBox()->setItemText(child - 1, text);
+}
+
+QAccessible::State QAccessibleToolBox::state(int child) const
+{
+ QWidget *childWidget = toolBox()->widget(child - 1);
+ if (!childWidget)
+ return QAccessibleWidgetEx::state(child);
+ QAccessible::State childState = QAccessible::Normal;
+ if (toolBox()->currentWidget() == childWidget)
+ childState |= QAccessible::Expanded;
+ else
+ childState |= QAccessible::Collapsed;
+ return childState;
+}
+
+QVariant QAccessibleToolBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+int QAccessibleToolBox::childCount() const
+{
+ return toolBox()->count();
+}
+
+int QAccessibleToolBox::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child)
+ return -1;
+ QWidget *childWidget = qobject_cast<QWidget *>(child->object());
+ if (!childWidget)
+ return -1;
+ int index = toolBox()->indexOf(childWidget);
+ if (index != -1)
+ ++index;
+ return index;
+}
+
+int QAccessibleToolBox::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+ if (entry <= 0 || entry > toolBox()->count())
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ int index = -1;
+ if (relation == QAccessible::Up)
+ index = entry - 2;
+ else if (relation == QAccessible::Down)
+ index = entry;
+ *target = QAccessible::queryAccessibleInterface(toolBox()->widget(index));
+ return *target ? 0: -1;
+}
+
+QToolBox * QAccessibleToolBox::toolBox() const
+{
+ return static_cast<QToolBox *>(object());
+}
+#endif // QT_NO_TOOLBOX
+
+// ======================= QAccessibleMdiArea ======================
+#ifndef QT_NO_MDIAREA
+QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget)
+ : QAccessibleWidgetEx(widget, LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QMdiArea *>(widget));
+}
+
+QAccessible::State QAccessibleMdiArea::state(int child) const
+{
+ if (child < 0)
+ return QAccessibleWidgetEx::state(child);
+ if (child == 0)
+ return QAccessible::Normal;
+ QList<QMdiSubWindow *> subWindows = mdiArea()->subWindowList();
+ if (subWindows.isEmpty() || child > subWindows.count())
+ return QAccessibleWidgetEx::state(child);
+ if (subWindows.at(child - 1) == mdiArea()->activeSubWindow())
+ return QAccessible::Focused;
+ return QAccessible::Normal;
+}
+
+QVariant QAccessibleMdiArea::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+int QAccessibleMdiArea::childCount() const
+{
+ return mdiArea()->subWindowList().count();
+}
+
+int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object() || mdiArea()->subWindowList().isEmpty())
+ return -1;
+ if (QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(child->object())) {
+ int index = mdiArea()->subWindowList().indexOf(window);
+ if (index != -1)
+ return ++index;
+ }
+ return -1;
+}
+
+int QAccessibleMdiArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+ QWidget *targetObject = 0;
+ QList<QMdiSubWindow *> subWindows = mdiArea()->subWindowList();
+ switch (relation) {
+ case Child:
+ if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count())
+ return -1;
+ targetObject = subWindows.at(entry - 1);
+ break;
+ case Up:
+ case Down:
+ case Left:
+ case Right:
+ targetObject = mdiAreaNavigate(mdiArea(), relation, entry);
+ break;
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ return *target ? 0: -1;
+}
+
+QMdiArea *QAccessibleMdiArea::mdiArea() const
+{
+ return static_cast<QMdiArea *>(object());
+}
+
+// ======================= QAccessibleMdiSubWindow ======================
+QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget)
+ : QAccessibleWidgetEx(widget, QAccessible::Window)
+{
+ Q_ASSERT(qobject_cast<QMdiSubWindow *>(widget));
+}
+
+QString QAccessibleMdiSubWindow::text(Text textType, int child) const
+{
+ if (textType == QAccessible::Name && (child == 0 || child == 1)) {
+ QString title = mdiSubWindow()->windowTitle();
+ title.replace(QLatin1String("[*]"), QLatin1String(""));
+ return title;
+ }
+ return QAccessibleWidgetEx::text(textType, child);
+}
+
+void QAccessibleMdiSubWindow::setText(Text textType, int child, const QString &text)
+{
+ if (textType == QAccessible::Name && (child == 0 || child == 1))
+ mdiSubWindow()->setWindowTitle(text);
+ else
+ QAccessibleWidgetEx::setText(textType, child, text);
+}
+
+QAccessible::State QAccessibleMdiSubWindow::state(int child) const
+{
+ if (child != 0 || !mdiSubWindow()->parent())
+ return QAccessibleWidgetEx::state(child);
+ QAccessible::State state = QAccessible::Normal | QAccessible::Focusable;
+ if (!mdiSubWindow()->isMaximized())
+ state |= (QAccessible::Movable | QAccessible::Sizeable);
+ if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget())
+ || QApplication::focusWidget() == mdiSubWindow())
+ state |= QAccessible::Focused;
+ if (!mdiSubWindow()->isVisible())
+ state |= QAccessible::Invisible;
+ if (!mdiSubWindow()->parentWidget()->contentsRect().contains(mdiSubWindow()->geometry()))
+ state |= QAccessible::Offscreen;
+ if (!mdiSubWindow()->isEnabled())
+ state |= QAccessible::Unavailable;
+ return state;
+}
+
+QVariant QAccessibleMdiSubWindow::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+int QAccessibleMdiSubWindow::childCount() const
+{
+ if (mdiSubWindow()->widget())
+ return 1;
+ return 0;
+}
+
+int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (child && child->object() && child->object() == mdiSubWindow()->widget())
+ return 1;
+ return -1;
+}
+
+int QAccessibleMdiSubWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+
+ if (!mdiSubWindow()->parent())
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+
+ QWidget *targetObject = 0;
+ QMdiSubWindow *source = mdiSubWindow();
+ switch (relation) {
+ case Child:
+ if (entry != 1 || !source->widget())
+ return -1;
+ targetObject = source->widget();
+ break;
+ case Up:
+ case Down:
+ case Left:
+ case Right: {
+ if (entry != 0)
+ break;
+ QWidget *parent = source->parentWidget();
+ while (parent && !parent->inherits("QMdiArea"))
+ parent = parent->parentWidget();
+ QMdiArea *mdiArea = qobject_cast<QMdiArea *>(parent);
+ if (!mdiArea)
+ break;
+ int index = mdiArea->subWindowList().indexOf(source);
+ if (index == -1)
+ break;
+ if (QWidget *dest = mdiAreaNavigate(mdiArea, relation, index + 1)) {
+ *target = QAccessible::queryAccessibleInterface(dest);
+ return *target ? 0 : -1;
+ }
+ break;
+ }
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ return *target ? 0: -1;
+}
+
+QRect QAccessibleMdiSubWindow::rect(int child) const
+{
+ if (mdiSubWindow()->isHidden())
+ return QRect();
+ if (!mdiSubWindow()->parent())
+ return QAccessibleWidgetEx::rect(child);
+ const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0));
+ if (child == 0)
+ return QRect(pos, mdiSubWindow()->size());
+ if (child == 1 && mdiSubWindow()->widget()) {
+ if (mdiSubWindow()->widget()->isHidden())
+ return QRect();
+ const QRect contentsRect = mdiSubWindow()->contentsRect();
+ return QRect(pos.x() + contentsRect.x(), pos.y() + contentsRect.y(),
+ contentsRect.width(), contentsRect.height());
+ }
+ return QRect();
+}
+
+int QAccessibleMdiSubWindow::childAt(int x, int y) const
+{
+ if (!mdiSubWindow()->isVisible())
+ return -1;
+ if (!mdiSubWindow()->parent())
+ return QAccessibleWidgetEx::childAt(x, y);
+ const QRect globalGeometry = rect(0);
+ if (!globalGeometry.isValid())
+ return -1;
+ const QRect globalChildGeometry = rect(1);
+ if (globalChildGeometry.isValid() && globalChildGeometry.contains(QPoint(x, y)))
+ return 1;
+ if (globalGeometry.contains(QPoint(x, y)))
+ return 0;
+ return -1;
+}
+
+QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const
+{
+ return static_cast<QMdiSubWindow *>(object());
+}
+#endif // QT_NO_MDIAREA
+
+// ======================= QAccessibleWorkspace ======================
+#ifndef QT_NO_WORKSPACE
+QAccessibleWorkspace::QAccessibleWorkspace(QWidget *widget)
+ : QAccessibleWidgetEx(widget, LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QWorkspace *>(widget));
+}
+
+QAccessible::State QAccessibleWorkspace::state(int child) const
+{
+ if (child < 0)
+ return QAccessibleWidgetEx::state(child);
+ if (child == 0)
+ return QAccessible::Normal;
+ QWidgetList subWindows = workspace()->windowList();
+ if (subWindows.isEmpty() || child > subWindows.count())
+ return QAccessibleWidgetEx::state(child);
+ if (subWindows.at(child - 1) == workspace()->activeWindow())
+ return QAccessible::Focused;
+ return QAccessible::Normal;
+}
+
+QVariant QAccessibleWorkspace::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+int QAccessibleWorkspace::childCount() const
+{
+ return workspace()->windowList().count();
+}
+
+int QAccessibleWorkspace::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object() || workspace()->windowList().isEmpty())
+ return -1;
+ if (QWidget *window = qobject_cast<QWidget *>(child->object())) {
+ int index = workspace()->windowList().indexOf(window);
+ if (index != -1)
+ return ++index;
+ }
+ return -1;
+}
+
+int QAccessibleWorkspace::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+ QWidget *targetObject = 0;
+ QWidgetList subWindows = workspace()->windowList();
+ switch (relation) {
+ case Child:
+ if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count())
+ return -1;
+ targetObject = subWindows.at(entry - 1);
+ break;
+ case Up:
+ case Down:
+ case Left:
+ case Right:
+ targetObject = mdiAreaNavigate(workspace(), relation, entry);
+ break;
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ return *target ? 0: -1;
+}
+
+QWorkspace *QAccessibleWorkspace::workspace() const
+{
+ return static_cast<QWorkspace *>(object());
+}
+#endif
+
+#ifndef QT_NO_DIALOGBUTTONBOX
+// ======================= QAccessibleDialogButtonBox ======================
+QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget)
+ : QAccessibleWidgetEx(widget, Grouping)
+{
+ Q_ASSERT(qobject_cast<QDialogButtonBox*>(widget));
+}
+
+QVariant QAccessibleDialogButtonBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+#endif // QT_NO_DIALOGBUTTONBOX
+
+#ifndef QT_NO_TEXTBROWSER
+QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget)
+ : QAccessibleTextEdit(widget)
+{
+ Q_ASSERT(qobject_cast<QTextBrowser *>(widget));
+}
+
+QAccessible::Role QAccessibleTextBrowser::role(int child) const
+{
+ if (child != 0)
+ return QAccessibleTextEdit::role(child);
+ return QAccessible::StaticText;
+}
+#endif // QT_NO_TEXTBROWSER
+
+#ifndef QT_NO_CALENDARWIDGET
+// ===================== QAccessibleCalendarWidget ========================
+QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget)
+ : QAccessibleWidgetEx(widget, Table)
+{
+ Q_ASSERT(qobject_cast<QCalendarWidget *>(widget));
+}
+
+QVariant QAccessibleCalendarWidget::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+int QAccessibleCalendarWidget::childCount() const
+{
+ return calendarWidget()->isNavigationBarVisible() ? 2 : 1;
+}
+
+int QAccessibleCalendarWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object() || childCount() <= 0)
+ return -1;
+ if (qobject_cast<QAbstractItemView *>(child->object()))
+ return childCount();
+ return 1;
+}
+
+int QAccessibleCalendarWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+ if (entry <= 0 || entry > childCount())
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ QWidget *targetWidget = 0;
+ switch (relation) {
+ case Child:
+ if (childCount() == 1) {
+ targetWidget = calendarView();
+ } else {
+ if (entry == 1)
+ targetWidget = navigationBar();
+ else
+ targetWidget = calendarView();
+ }
+ break;
+ case Up:
+ if (entry == 2)
+ targetWidget = navigationBar();
+ break;
+ case Down:
+ if (entry == 1 && childCount() == 2)
+ targetWidget = calendarView();
+ break;
+ default:
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+ }
+ *target = queryAccessibleInterface(targetWidget);
+ return *target ? 0: -1;
+}
+
+QRect QAccessibleCalendarWidget::rect(int child) const
+{
+ if (!calendarWidget()->isVisible() || child > childCount())
+ return QRect();
+ if (child == 0)
+ return QAccessibleWidgetEx::rect(child);
+ QWidget *childWidget = 0;
+ if (childCount() == 2)
+ childWidget = child == 1 ? navigationBar() : calendarView();
+ else
+ childWidget = calendarView();
+ return QRect(childWidget->mapToGlobal(QPoint(0, 0)), childWidget->size());
+}
+
+int QAccessibleCalendarWidget::childAt(int x, int y) const
+{
+ const QPoint globalTargetPos = QPoint(x, y);
+ if (!rect(0).contains(globalTargetPos))
+ return -1;
+ if (rect(1).contains(globalTargetPos))
+ return 1;
+ if (rect(2).contains(globalTargetPos))
+ return 2;
+ return 0;
+}
+
+QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const
+{
+ return static_cast<QCalendarWidget *>(object());
+}
+
+QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
+{
+ foreach (QObject *child, calendarWidget()->children()) {
+ if (child->objectName() == QLatin1String("qt_calendar_calendarview"))
+ return static_cast<QAbstractItemView *>(child);
+ }
+ return 0;
+}
+
+QWidget *QAccessibleCalendarWidget::navigationBar() const
+{
+ foreach (QObject *child, calendarWidget()->children()) {
+ if (child->objectName() == QLatin1String("qt_calendar_navigationbar"))
+ return static_cast<QWidget *>(child);
+ }
+ return 0;
+}
+#endif // QT_NO_CALENDARWIDGET
+
+#ifndef QT_NO_DOCKWIDGET
+QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget)
+ : QAccessibleWidgetEx(widget, Window)
+{
+
+}
+
+int QAccessibleDockWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
+{
+ if (relation == Child) {
+ if (entry == 1) {
+ *iface = new QAccessibleTitleBar(dockWidget());
+ return 0;
+ } else if (entry == 2) {
+ if (dockWidget()->widget())
+ *iface = QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ return 0;
+ }
+ *iface = 0;
+ return -1;
+ }
+ return QAccessibleWidgetEx::navigate(relation, entry, iface);
+}
+
+int QAccessibleDockWidget::childAt(int x, int y) const
+{
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(x,y))
+ return i;
+ }
+ return -1;
+}
+
+int QAccessibleDockWidget::childCount() const
+{
+ return dockWidget()->widget() ? 2 : 1;
+}
+
+int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (child) {
+ if (child->role(0) == TitleBar) {
+ return 1;
+ } else {
+ return 2; //###
+ }
+ }
+ return -1;
+}
+
+QAccessible::Role QAccessibleDockWidget::role(int child) const
+{
+ switch (child) {
+ case 0:
+ return Window;
+ case 1:
+ return TitleBar;
+ case 2:
+ //###
+ break;
+ default:
+ break;
+ }
+ return NoRole;
+}
+
+QAccessible::State QAccessibleDockWidget::state(int child) const
+{
+ //### mark tabified widgets as invisible
+ return QAccessibleWidgetEx::state(child);
+}
+
+QRect QAccessibleDockWidget::rect (int child ) const
+{
+ QRect rect;
+ bool mapToGlobal = true;
+ if (child == 0) {
+ if (dockWidget()->isFloating()) {
+ rect = dockWidget()->frameGeometry();
+ mapToGlobal = false;
+ } else {
+ rect = dockWidget()->rect();
+ }
+ }else if (child == 1) {
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
+ rect = layout->titleArea();
+ }else if (child == 2) {
+ if (dockWidget()->widget())
+ rect = dockWidget()->widget()->geometry();
+ }
+ if (rect.isNull())
+ return rect;
+
+ if (mapToGlobal)
+ rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
+
+ return rect;
+}
+
+QVariant QAccessibleDockWidget::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+QDockWidget *QAccessibleDockWidget::dockWidget() const
+{
+ return static_cast<QDockWidget *>(object());
+}
+
+////
+// QAccessibleTitleBar
+////
+QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget)
+ : m_dockWidget(widget)
+{
+
+}
+
+int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
+{
+ if (entry == 0 || relation == Self) {
+ *iface = new QAccessibleTitleBar(dockWidget());
+ return 0;
+ }
+ switch (relation) {
+ case Child:
+ case FocusChild:
+ if (entry >= 1) {
+ QDockWidgetLayout *layout = dockWidgetLayout();
+ int index = 1;
+ int role;
+ for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
+ QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
+ if (!w->isVisible())
+ continue;
+ if (index == entry)
+ break;
+ ++index;
+ }
+ *iface = 0;
+ return role > QDockWidgetLayout::FloatButton ? -1 : index;
+ }
+ break;
+ case Ancestor:
+ {
+ QAccessibleDockWidget *target = new QAccessibleDockWidget(dockWidget());
+ int index;
+ if (entry == 1) {
+ *iface = target;
+ return 0;
+ }
+ index = target->navigate(Ancestor, entry - 1, iface);
+ delete target;
+ return index;
+
+ break;}
+ case Sibling:
+ return navigate(Child, entry, iface);
+ break;
+ default:
+ break;
+ }
+ *iface = 0;
+ return -1;
+}
+
+QAccessible::Relation QAccessibleTitleBar::relationTo(int /*child*/, const QAccessibleInterface * /*other*/, int /*otherChild*/) const
+{
+ return Unrelated; //###
+}
+
+int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const
+{
+ return -1;
+}
+
+int QAccessibleTitleBar::childCount() const
+{
+ QDockWidgetLayout *layout = dockWidgetLayout();
+ int count = 0;
+ for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
+ QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
+ if (w && w->isVisible())
+ ++count;
+ }
+ return count;
+}
+
+QString QAccessibleTitleBar::text(Text t, int child) const
+{
+ if (!child) {
+ if (t == Value) {
+ return dockWidget()->windowTitle();
+ }
+ }
+ return QString();
+}
+
+QAccessible::State QAccessibleTitleBar::state(int child) const
+{
+ QAccessible::State state = Normal;
+ if (child) {
+ QDockWidgetLayout *layout = dockWidgetLayout();
+ QAbstractButton *b = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
+ if (b) {
+ if (b->isDown())
+ state |= Pressed;
+ }
+ } else {
+ QDockWidget *w = dockWidget();
+ if (w->testAttribute(Qt::WA_WState_Visible) == false)
+ state |= Invisible;
+ if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
+ state |= Focusable;
+ if (w->hasFocus())
+ state |= Focused;
+ if (!w->isEnabled())
+ state |= Unavailable;
+ }
+
+ return state;
+}
+
+QRect QAccessibleTitleBar::rect (int child ) const
+{
+ bool mapToGlobal = true;
+ QRect rect;
+ if (child == 0) {
+ if (dockWidget()->isFloating()) {
+ rect = dockWidget()->frameGeometry();
+ QPoint globalPos = dockWidget()->mapToGlobal( dockWidget()->widget()->rect().topLeft() );
+ globalPos.ry()--;
+ rect.setBottom(globalPos.y());
+ mapToGlobal = false;
+ } else {
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
+ rect = layout->titleArea();
+ }
+ }else if (child >= 1 && child <= childCount()) {
+ QDockWidgetLayout *layout = dockWidgetLayout();
+ int index = 1;
+ for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
+ QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
+ if (!w || !w->isVisible())
+ continue;
+ if (index == child) {
+ rect = w->geometry();
+ break;
+ }
+ ++index;
+ }
+ }
+ if (rect.isNull())
+ return rect;
+
+ if (mapToGlobal)
+ rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
+ return rect;
+}
+
+int QAccessibleTitleBar::childAt(int x, int y) const
+{
+ for (int i = childCount(); i >= 0; --i) {
+ if (rect(i).contains(x,y))
+ return i;
+ }
+ return -1;
+}
+
+QObject *QAccessibleTitleBar::object() const
+{
+ return 0;
+}
+
+QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const
+{
+ return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
+}
+
+QDockWidget *QAccessibleTitleBar::dockWidget() const
+{
+ return m_dockWidget;
+}
+
+QString QAccessibleTitleBar::actionText(int action, Text t, int child) const
+{
+ QString str;
+ if (child >= 1 && child <= childCount()) {
+ if (t == Name) {
+ switch (action) {
+ case Press:
+ case DefaultAction:
+ if (child == QDockWidgetLayout::CloseButton) {
+ str = QDockWidget::tr("Close");
+ } else if (child == QDockWidgetLayout::FloatButton) {
+ str = dockWidget()->isFloating() ? QDockWidget::tr("Dock")
+ : QDockWidget::tr("Float");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return str;
+}
+
+bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/)
+{
+ if (!child || !dockWidget()->isEnabled())
+ return false;
+
+ switch (action) {
+ case DefaultAction:
+ case Press: {
+ QDockWidgetLayout *layout = dockWidgetLayout();
+ QAbstractButton *btn = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
+ if (btn)
+ btn->animateClick();
+ return true;
+ break;}
+ default:
+ break;
+ }
+
+ return false;
+}
+
+int QAccessibleTitleBar::userActionCount (int /*child*/) const
+{
+ return 0;
+}
+
+QAccessible::Role QAccessibleTitleBar::role(int child) const
+{
+ switch (child) {
+ case 0:
+ return TitleBar;
+ break;
+ default:
+ if (child >= 1 && child <= childCount())
+ return PushButton;
+ break;
+ }
+
+ return NoRole;
+}
+
+void QAccessibleTitleBar::setText(Text /*t*/, int /*child*/, const QString &/*text*/)
+{
+
+}
+
+bool QAccessibleTitleBar::isValid() const
+{
+ return dockWidget();
+}
+
+#endif // QT_NO_DOCKWIDGET
+
+#ifndef QT_NO_TEXTEDIT
+void QAccessibleTextEdit::addSelection(int startOffset, int endOffset)
+{
+ setSelection(0, startOffset, endOffset);
+}
+
+QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset)
+{
+ // TODO - wait for a definition of attributes
+ Q_UNUSED(offset);
+ Q_UNUSED(startOffset);
+ Q_UNUSED(endOffset);
+ return QString();
+}
+
+int QAccessibleTextEdit::cursorPosition()
+{
+ return textEdit()->textCursor().position();
+}
+
+QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType)
+{
+ QTextEdit *edit = textEdit();
+ QTextCursor cursor(edit->document());
+ cursor.setPosition(offset);
+
+ if (cursor.position() != offset)
+ return QRect();
+
+ QRect r = edit->cursorRect(cursor);
+ if (cursor.movePosition(QTextCursor::NextCharacter)) {
+ r.setWidth(edit->cursorRect(cursor).y() - r.y());
+ } else {
+ // we don't know the width of the character - maybe because we're at document end
+ // in that case, IAccessible2 tells us to return the width of a default character
+ int averageCharWidth = QFontMetrics(cursor.charFormat().font()).averageCharWidth();
+ if (edit->layoutDirection() == Qt::RightToLeft)
+ averageCharWidth *= -1;
+ r.setWidth(averageCharWidth);
+ }
+
+ switch (coordType) {
+ case RelativeToScreen:
+ r.moveTo(edit->viewport()->mapToGlobal(r.topLeft()));
+ break;
+ case RelativeToParent:
+ break;
+ }
+
+ return r;
+}
+
+int QAccessibleTextEdit::selectionCount()
+{
+ return textEdit()->textCursor().hasSelection() ? 1 : 0;
+}
+
+int QAccessibleTextEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType)
+{
+ QTextEdit *edit = textEdit();
+
+ QPoint p = point;
+ if (coordType == RelativeToScreen)
+ p = edit->viewport()->mapFromGlobal(p);
+ // convert to document coordinates
+ p += QPoint(edit->horizontalScrollBar()->value(), edit->verticalScrollBar()->value());
+
+ return edit->document()->documentLayout()->hitTest(p, Qt::ExactHit);
+}
+
+void QAccessibleTextEdit::selection(int selectionIndex, int *startOffset, int *endOffset)
+{
+ *startOffset = *endOffset = 0;
+ QTextCursor cursor = textEdit()->textCursor();
+
+ if (selectionIndex != 0 || !cursor.hasSelection())
+ return;
+
+ *startOffset = cursor.selectionStart();
+ *endOffset = cursor.selectionEnd();
+}
+
+QString QAccessibleTextEdit::text(int startOffset, int endOffset)
+{
+ QTextCursor cursor(textEdit()->document());
+
+ cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
+ cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
+
+ return cursor.selectedText();
+}
+
+QString QAccessibleTextEdit::textBeforeOffset (int offset, BoundaryType boundaryType,
+ int *startOffset, int *endOffset)
+{
+ // TODO - what exactly is before?
+ Q_UNUSED(offset);
+ Q_UNUSED(boundaryType);
+ Q_UNUSED(startOffset);
+ Q_UNUSED(endOffset);
+ return QString();
+}
+
+QString QAccessibleTextEdit::textAfterOffset(int offset, BoundaryType boundaryType,
+ int *startOffset, int *endOffset)
+{
+ // TODO - what exactly is after?
+ Q_UNUSED(offset);
+ Q_UNUSED(boundaryType);
+ Q_UNUSED(startOffset);
+ Q_UNUSED(endOffset);
+ return QString();
+}
+
+QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType,
+ int *startOffset, int *endOffset)
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+
+ *startOffset = *endOffset = -1;
+ QTextEdit *edit = textEdit();
+
+ QTextCursor cursor(edit->document());
+ if (offset >= characterCount())
+ return QString();
+
+ switch (boundaryType) {
+ case CharBoundary:
+ cursor.setPosition(offset);
+ *startOffset = cursor.position();
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ *endOffset = cursor.position();
+ break;
+ case WordBoundary:
+ cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
+ *startOffset = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ *endOffset = cursor.position();
+ break;
+ case SentenceBoundary:
+ // TODO - what's a sentence?
+ return QString();
+ case LineBoundary:
+ cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
+ *startOffset = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
+ *endOffset = cursor.position();
+ break;
+ case ParagraphBoundary:
+ cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
+ *startOffset = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ *endOffset = cursor.position();
+ break;
+ case NoBoundary: {
+ *startOffset = 0;
+ const QString txt = edit->toPlainText();
+ *endOffset = txt.count();
+ return txt; }
+ default:
+ qDebug("AccessibleTextAdaptor::textAtOffset: Unknown boundary type %d", boundaryType);
+ return QString();
+ }
+
+ return cursor.selectedText();
+}
+
+void QAccessibleTextEdit::removeSelection(int selectionIndex)
+{
+ if (selectionIndex != 0)
+ return;
+
+ QTextCursor cursor = textEdit()->textCursor();
+ cursor.clearSelection();
+ textEdit()->setTextCursor(cursor);
+}
+
+void QAccessibleTextEdit::setCursorPosition(int position)
+{
+ QTextCursor cursor = textEdit()->textCursor();
+ cursor.setPosition(position);
+ textEdit()->setTextCursor(cursor);
+}
+
+void QAccessibleTextEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
+{
+ if (selectionIndex != 0)
+ return;
+
+ QTextCursor cursor = textEdit()->textCursor();
+ cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
+ cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
+ textEdit()->setTextCursor(cursor);
+}
+
+int QAccessibleTextEdit::characterCount()
+{
+ return textEdit()->toPlainText().count();
+}
+
+void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
+{
+ QTextEdit *edit = textEdit();
+
+ QTextCursor cursor(edit->document());
+ cursor.setPosition(startIndex);
+ QRect r = edit->cursorRect(cursor);
+
+ cursor.setPosition(endIndex);
+ r.setBottomRight(edit->cursorRect(cursor).bottomRight());
+
+ r.moveTo(r.x() + edit->horizontalScrollBar()->value(),
+ r.y() + edit->verticalScrollBar()->value());
+
+ // E V I L, but ensureVisible is not public
+ if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r)))
+ qWarning("AccessibleTextEdit::scrollToSubstring failed!");
+}
+
+static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endOffset)
+{
+ QTextCursor cursor(textEdit->document());
+ cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
+ cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
+
+ return cursor;
+}
+
+void QAccessibleTextEdit::copyText(int startOffset, int endOffset)
+{
+ QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
+
+ if (!cursor.hasSelection())
+ return;
+
+// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
+}
+
+void QAccessibleTextEdit::deleteText(int startOffset, int endOffset)
+{
+ QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
+
+ cursor.removeSelectedText();
+}
+
+void QAccessibleTextEdit::insertText(int offset, const QString &text)
+{
+ QTextCursor cursor(textEdit()->document());
+ cursor.setPosition(offset);
+
+ cursor.insertText(text);
+}
+
+void QAccessibleTextEdit::cutText(int startOffset, int endOffset)
+{
+ QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
+
+ if (!cursor.hasSelection())
+ return;
+
+// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
+ cursor.removeSelectedText();
+}
+
+void QAccessibleTextEdit::pasteText(int offset)
+{
+ QTextEdit *edit = textEdit();
+
+ QTextCursor oldCursor = edit->textCursor();
+ QTextCursor newCursor = oldCursor;
+ newCursor.setPosition(offset);
+
+ edit->setTextCursor(newCursor);
+#ifndef QT_NO_CLIPBOARD
+ edit->paste();
+#endif
+ edit->setTextCursor(oldCursor);
+}
+
+void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text)
+{
+ QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
+
+ cursor.removeSelectedText();
+ cursor.insertText(text);
+}
+
+void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes)
+{
+ // TODO
+ Q_UNUSED(startOffset);
+ Q_UNUSED(endOffset);
+ Q_UNUSED(attributes);
+}
+
+#endif // QT_NO_TEXTEDIT
+
+#ifndef QT_NO_MAINWINDOW
+QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
+ : QAccessibleWidgetEx(widget, Application) { }
+
+QVariant QAccessibleMainWindow::invokeMethodEx(QAccessible::Method /*method*/, int /*child*/, const QVariantList & /*params*/)
+{
+ return QVariant();
+}
+
+int QAccessibleMainWindow::childCount() const
+{
+ QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ return kids.count();
+}
+
+int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const
+{
+ QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ int childIndex = kids.indexOf(static_cast<QWidget*>(iface->object()));
+ return childIndex == -1 ? -1 : ++childIndex;
+}
+
+int QAccessibleMainWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
+{
+ if (relation == Child && entry >= 1) {
+ QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ if (entry <= kids.count()) {
+ *iface = QAccessible::queryAccessibleInterface(kids.at(entry - 1));
+ return *iface ? 0 : -1;
+ }
+ }
+ return QAccessibleWidgetEx::navigate(relation, entry, iface);
+}
+
+int QAccessibleMainWindow::childAt(int x, int y) const
+{
+ QWidget *w = widget();
+ if (!w->isVisible())
+ return -1;
+ QPoint gp = w->mapToGlobal(QPoint(0, 0));
+ if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
+ return -1;
+
+ QWidgetList kids = childWidgets(mainWindow(), true);
+ QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y));
+ for (int i = 0; i < kids.size(); ++i) {
+ QWidget *child = kids.at(i);
+ if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
+QMainWindow *QAccessibleMainWindow::mainWindow() const
+{
+ return qobject_cast<QMainWindow *>(object());
+}
+
+#endif //QT_NO_MAINWINDOW
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
new file mode 100644
index 0000000000..64c2bde188
--- /dev/null
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEWIDGETS_H
+#define QACCESSIBLEWIDGETS_H
+
+#include <QtGui/qaccessible2.h>
+#include <QtGui/qaccessiblewidget.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+class QStackedWidget;
+class QToolBox;
+class QMdiArea;
+class QMdiSubWindow;
+class QWorkspace;
+class QRubberBand;
+class QTextBrowser;
+class QCalendarWidget;
+class QAbstractItemView;
+class QDockWidget;
+class QDockWidgetLayout;
+class QMainWindow;
+
+#ifndef QT_NO_TEXTEDIT
+class QAccessibleTextEdit : public QAccessibleWidgetEx, public QAccessibleTextInterface,
+ public QAccessibleEditableTextInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleTextEdit(QWidget *o);
+
+ QString text(Text t, int child) const;
+ void setText(Text t, int control, const QString &text);
+ Role role(int child) const;
+
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+
+ QRect rect(int child) const;
+ int childAt(int x, int y) const;
+
+ int childCount() const;
+
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset);
+ QString attributes(int offset, int *startOffset, int *endOffset);
+ int cursorPosition();
+ QRect characterRect(int offset, QAccessible2::CoordinateType coordType);
+ int selectionCount();
+ int offsetAtPoint(const QPoint &point, QAccessible2::CoordinateType coordType);
+ void selection(int selectionIndex, int *startOffset, int *endOffset);
+ QString text(int startOffset, int endOffset);
+ QString textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+ QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+ QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+ void removeSelection(int selectionIndex);
+ void setCursorPosition(int position);
+ void setSelection(int selectionIndex, int startOffset, int endOffset);
+ int characterCount();
+ void scrollToSubstring(int startIndex, int endIndex);
+
+ // QAccessibleEditableTextInterface
+ void copyText(int startOffset, int endOffset);
+ void deleteText(int startOffset, int endOffset);
+ void insertText(int offset, const QString &text);
+ void cutText(int startOffset, int endOffset);
+ void pasteText(int offset);
+ void replaceText(int startOffset, int endOffset, const QString &text);
+ void setAttributes(int startOffset, int endOffset, const QString &attributes);
+
+protected:
+ QTextEdit *textEdit() const;
+
+private:
+ int childOffset;
+};
+#endif // QT_NO_TEXTEDIT
+
+class QAccessibleStackedWidget : public QAccessibleWidgetEx
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleStackedWidget(QWidget *widget);
+
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childAt(int x, int y) const;
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+
+protected:
+ QStackedWidget *stackedWidget() const;
+};
+
+class QAccessibleToolBox : public QAccessibleWidgetEx
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleToolBox(QWidget *widget);
+
+ QString text(Text textType, int child) const;
+ void setText(Text textType, int child, const QString &text);
+ State state(int child) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+
+protected:
+ QToolBox *toolBox() const;
+};
+
+#ifndef QT_NO_MDIAREA
+class QAccessibleMdiArea : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleMdiArea(QWidget *widget);
+
+ State state(int child) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+
+protected:
+ QMdiArea *mdiArea() const;
+};
+
+class QAccessibleMdiSubWindow : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleMdiSubWindow(QWidget *widget);
+
+ QString text(Text textType, int child) const;
+ void setText(Text textType, int child, const QString &text);
+ State state(int child) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+ QRect rect(int child) const;
+ int childAt(int x, int y) const;
+
+protected:
+ QMdiSubWindow *mdiSubWindow() const;
+};
+#endif // QT_NO_MDIAREA
+
+#ifndef QT_NO_WORKSPACE
+class QAccessibleWorkspace : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleWorkspace(QWidget *widget);
+
+ State state(int child) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+
+protected:
+ QWorkspace *workspace() const;
+};
+#endif
+
+class QAccessibleDialogButtonBox : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleDialogButtonBox(QWidget *widget);
+
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+};
+
+#ifndef QT_NO_TEXTBROWSER
+class QAccessibleTextBrowser : public QAccessibleTextEdit
+{
+public:
+ explicit QAccessibleTextBrowser(QWidget *widget);
+
+ Role role(int child) const;
+};
+#endif // QT_NO_TEXTBROWSER
+
+#ifndef QT_NO_CALENDARWIDGET
+class QAccessibleCalendarWidget : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleCalendarWidget(QWidget *widget);
+
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
+ QRect rect(int child) const;
+ int childAt(int x, int y) const;
+
+protected:
+ QCalendarWidget *calendarWidget() const;
+
+private:
+ QAbstractItemView *calendarView() const;
+ QWidget *navigationBar() const;
+};
+#endif // QT_NO_CALENDARWIDGET
+
+#ifndef QT_NO_DOCKWIDGET
+class QAccessibleDockWidget: public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleDockWidget(QWidget *widget);
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int childCount() const;
+ QRect rect (int child ) const;
+ Role role(int child) const;
+ State state(int child) const;
+ int childAt(int x, int y) const;
+
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ QDockWidget *dockWidget() const;
+};
+
+class QAccessibleTitleBar : public QAccessibleInterface
+{
+public:
+ explicit QAccessibleTitleBar(QDockWidget *widget);
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList& params = QVariantList());
+ int userActionCount ( int child) const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ int childCount() const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+ void setText(Text t, int child, const QString &text);
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ QRect rect (int child) const;
+ State state(int child) const;
+ int childAt(int x, int y) const;
+ QObject *object() const;
+ bool isValid() const;
+
+
+ QPointer<QDockWidget> m_dockWidget;
+
+ QDockWidget *dockWidget() const;
+ QDockWidgetLayout *dockWidgetLayout() const;
+};
+
+#endif // QT_NO_DOCKWIDGET
+
+#ifndef QT_NO_MAINWINDOW
+class QAccessibleMainWindow : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleMainWindow(QWidget *widget);
+
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ int childCount() const;
+ int navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const;
+ int indexOfChild(const QAccessibleInterface *iface) const;
+ int childAt(int x, int y) const;
+ QMainWindow *mainWindow() const;
+
+};
+#endif //QT_NO_MAINWINDOW
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // QACESSIBLEWIDGETS_H
diff --git a/src/plugins/accessible/widgets/rangecontrols.cpp b/src/plugins/accessible/widgets/rangecontrols.cpp
new file mode 100644
index 0000000000..1f5407a631
--- /dev/null
+++ b/src/plugins/accessible/widgets/rangecontrols.cpp
@@ -0,0 +1,991 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rangecontrols.h"
+
+#include <qslider.h>
+#include <qdial.h>
+#include <qspinbox.h>
+#include <qscrollbar.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qdebug.h>
+#include <qglobal.h>
+#include <QDoubleSpinBox>
+#include <QDial>
+#include <qmath.h>
+#include <private/qmath_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+extern QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
+#ifndef QT_NO_SCROLLBAR
+extern QStyleOptionSlider Q_GUI_EXPORT qt_qscrollbarStyleOption(QScrollBar *scrollBar);
+#endif
+#ifndef QT_NO_SLIDER
+extern QStyleOptionSlider Q_GUI_EXPORT qt_qsliderStyleOption(QSlider *slider);
+#endif
+
+#ifndef QT_NO_SPINBOX
+QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
+: QAccessibleWidgetEx(w, SpinBox)
+{
+ Q_ASSERT(abstractSpinBox());
+}
+
+/*!
+ Returns the underlying QAbstractSpinBox.
+*/
+QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
+{
+ return qobject_cast<QAbstractSpinBox*>(object());
+}
+
+/*! \reimp */
+int QAccessibleAbstractSpinBox::childCount() const
+{
+ if (!abstractSpinBox()->isVisible())
+ return 0;
+ return ValueDown;
+}
+
+/*! \reimp */
+QRect QAccessibleAbstractSpinBox::rect(int child) const
+{
+ QRect rect;
+ if (!abstractSpinBox()->isVisible())
+ return rect;
+ QStyleOptionSpinBox so;
+ so.rect = widget()->rect();
+ switch(child) {
+ case Editor:
+ rect = widget()->style()->subControlRect(QStyle::CC_SpinBox, &so,
+ QStyle::SC_SpinBoxEditField, widget());
+ break;
+ case ValueUp:
+ rect = widget()->style()->subControlRect(QStyle::CC_SpinBox, &so,
+ QStyle::SC_SpinBoxUp, widget());
+ break;
+ case ValueDown:
+ rect = widget()->style()->subControlRect(QStyle::CC_SpinBox, &so,
+ QStyle::SC_SpinBoxDown, widget());
+ break;
+ default:
+ rect = so.rect;
+ break;
+ }
+ QPoint tl = widget()->mapToGlobal(QPoint(0, 0));
+ return QRect(tl.x() + rect.x(), tl.y() + rect.y(), rect.width(), rect.height());
+}
+
+/*! \reimp */
+int QAccessibleAbstractSpinBox::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+
+ if (entry) switch (rel) {
+ case Child:
+ return entry <= childCount() ? entry : -1;
+ case QAccessible::Left:
+ return (entry == ValueUp || entry == ValueDown) ? Editor : -1;
+ case QAccessible::Right:
+ return entry == Editor ? ValueUp : -1;
+ case QAccessible::Up:
+ return entry == ValueDown ? ValueUp : -1;
+ case QAccessible::Down:
+ return entry == ValueUp ? ValueDown : -1;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::navigate(rel, entry, target);
+}
+
+/*! \reimp */
+QString QAccessibleAbstractSpinBox::text(Text t, int child) const
+{
+ if (!abstractSpinBox()->isVisible())
+ return QString();
+ switch (t) {
+ case Name:
+ switch (child) {
+ case ValueUp:
+ return QSpinBox::tr("More");
+ case ValueDown:
+ return QSpinBox::tr("Less");
+ }
+ break;
+ case Value:
+ if (child == Editor || child == SpinBoxSelf)
+ return abstractSpinBox()->text();
+ break;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::text(t, 0);
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleAbstractSpinBox::role(int child) const
+{
+ switch(child) {
+ case Editor:
+ return EditableText;
+ case ValueUp:
+ case ValueDown:
+ return PushButton;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::role(child);
+}
+
+/*! \reimp */
+bool QAccessibleAbstractSpinBox::doAction(int action, int child, const QVariantList &params)
+{
+ if (!widget()->isEnabled())
+ return false;
+
+ if (action == Press) {
+ switch(child) {
+ case ValueUp:
+ abstractSpinBox()->stepUp();
+ return true;
+ case ValueDown:
+ abstractSpinBox()->stepDown();
+ return true;
+ default:
+ break;
+ }
+ }
+ return QAccessibleWidgetEx::doAction(action, 0, params);
+}
+
+QVariant QAccessibleAbstractSpinBox::currentValue()
+{
+ QVariant result = abstractSpinBox()->property("value");
+ QVariant::Type type = result.type();
+
+ // IA2 only allows numeric types
+ if (type == QVariant::Int || type == QVariant::UInt || type == QVariant::LongLong
+ || type == QVariant::ULongLong || type == QVariant::Double)
+ return result;
+
+ return QVariant();
+}
+
+void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value)
+{
+ abstractSpinBox()->setProperty("setValue", value);
+}
+
+QVariant QAccessibleAbstractSpinBox::maximumValue()
+{
+ return abstractSpinBox()->property("maximum");
+}
+
+QVariant QAccessibleAbstractSpinBox::minimumValue()
+{
+ return abstractSpinBox()->property("minimum");
+}
+
+QVariant QAccessibleAbstractSpinBox::invokeMethodEx(Method method, int child, const QVariantList &params)
+{
+ switch (method) {
+ case ListSupportedMethods: {
+ QSet<QAccessible::Method> set;
+ set << ListSupportedMethods;
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
+ }
+ default:
+ return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
+ }
+}
+
+
+/*!
+ \class QAccessibleSpinBox
+ \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ \enum QAccessibleAbstractSpinBox::SpinBoxElements
+
+ This enum identifies the components of the spin box.
+
+ \value SpinBoxSelf The spin box as a whole
+ \value Editor The line edit sub-widget.
+ \value ValueUp The up sub-widget (i.e. the up arrow or + button)
+ \value ValueDown The down sub-widget (i.e. the down arrow or - button)
+*/
+
+/*!
+ Constructs a QAccessibleSpinWidget object for \a w.
+*/
+QAccessibleSpinBox::QAccessibleSpinBox(QWidget *w)
+: QAccessibleAbstractSpinBox(w)
+{
+ Q_ASSERT(spinBox());
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+ addControllingSignal(QLatin1String("valueChanged(QString)"));
+}
+
+/*!
+ Returns the underlying QSpinBox.
+*/
+QSpinBox *QAccessibleSpinBox::spinBox() const
+{
+ return qobject_cast<QSpinBox*>(object());
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleSpinBox::state(int child) const
+{
+ State state = QAccessibleAbstractSpinBox::state(child);
+ switch(child) {
+ case ValueUp:
+ if (spinBox()->value() >= spinBox()->maximum())
+ state |= Unavailable;
+ return state;
+ case ValueDown:
+ if (spinBox()->value() <= spinBox()->minimum())
+ state |= Unavailable;
+ return state;
+ default:
+ break;
+ }
+ return state;
+}
+
+/*! \reimp */
+bool QAccessibleSpinBox::doAction(int action, int child, const QVariantList &params)
+{
+ if (!widget()->isEnabled())
+ return false;
+
+ if (action == Press) {
+ switch(child) {
+ case ValueUp:
+ if (spinBox()->value() >= spinBox()->maximum())
+ return false;
+ spinBox()->stepUp();
+ return true;
+ case ValueDown:
+ if (spinBox()->value() <= spinBox()->minimum())
+ return false;
+ spinBox()->stepDown();
+ return true;
+ default:
+ break;
+ }
+ }
+ return QAccessibleAbstractSpinBox::doAction(action, 0, params);
+}
+
+// ================================== QAccessibleDoubleSpinBox ==================================
+QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget)
+ : QAccessibleWidgetEx(widget, SpinBox)
+{
+ Q_ASSERT(qobject_cast<QDoubleSpinBox *>(widget));
+ addControllingSignal(QLatin1String("valueChanged(double)"));
+ addControllingSignal(QLatin1String("valueChanged(QString)"));
+}
+
+/*!
+ Returns the underlying QDoubleSpinBox.
+*/
+QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const
+{
+ return static_cast<QDoubleSpinBox*>(object());
+}
+
+/*! \reimp */
+int QAccessibleDoubleSpinBox::childCount() const
+{
+ if (!doubleSpinBox()->isVisible())
+ return 0;
+ return ValueDown;
+}
+
+/*! \reimp */
+QRect QAccessibleDoubleSpinBox::rect(int child) const
+{
+ QRect rect;
+ if (!doubleSpinBox()->isVisible())
+ return rect;
+ QStyleOptionSpinBox spinBoxOption;
+ spinBoxOption.initFrom(doubleSpinBox());
+ switch (child) {
+ case Editor:
+ rect = doubleSpinBox()->style()->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
+ QStyle::SC_SpinBoxEditField, doubleSpinBox());
+ break;
+ case ValueUp:
+ rect = doubleSpinBox()->style()->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
+ QStyle::SC_SpinBoxUp, doubleSpinBox());
+ break;
+ case ValueDown:
+ rect = doubleSpinBox()->style()->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
+ QStyle::SC_SpinBoxDown, doubleSpinBox());
+ break;
+ default:
+ rect = spinBoxOption.rect;
+ break;
+ }
+ const QPoint globalPos = doubleSpinBox()->mapToGlobal(QPoint(0, 0));
+ return QRect(globalPos.x() + rect.x(), globalPos.y() + rect.y(), rect.width(), rect.height());
+}
+
+/*! \reimp */
+int QAccessibleDoubleSpinBox::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
+{
+ if (entry <= 0)
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+
+ *target = 0;
+ switch (relation) {
+ case Child:
+ return entry <= childCount() ? entry : -1;
+ case QAccessible::Left:
+ return (entry == ValueUp || entry == ValueDown) ? Editor : -1;
+ case QAccessible::Right:
+ return entry == Editor ? ValueUp : -1;
+ case QAccessible::Up:
+ return entry == ValueDown ? ValueUp : -1;
+ case QAccessible::Down:
+ return entry == ValueUp ? ValueDown : -1;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::navigate(relation, entry, target);
+}
+
+QVariant QAccessibleDoubleSpinBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+/*! \reimp */
+QString QAccessibleDoubleSpinBox::text(Text textType, int child) const
+{
+ if (!doubleSpinBox()->isVisible())
+ return QString();
+ switch (textType) {
+ case Name:
+ if (child == ValueUp)
+ return QDoubleSpinBox::tr("More");
+ else if (child == ValueDown)
+ return QDoubleSpinBox::tr("Less");
+ break;
+ case Value:
+ if (child == Editor || child == SpinBoxSelf)
+ return doubleSpinBox()->textFromValue(doubleSpinBox()->value());
+ break;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::text(textType, 0);
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleDoubleSpinBox::role(int child) const
+{
+ switch (child) {
+ case Editor:
+ return EditableText;
+ case ValueUp:
+ case ValueDown:
+ return PushButton;
+ default:
+ break;
+ }
+ return QAccessibleWidgetEx::role(child);
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleDoubleSpinBox::state(int child) const
+{
+ State state = QAccessibleWidgetEx::state(child);
+ switch (child) {
+ case ValueUp:
+ if (doubleSpinBox()->value() >= doubleSpinBox()->maximum())
+ state |= Unavailable;
+ break;
+ case ValueDown:
+ if (doubleSpinBox()->value() <= doubleSpinBox()->minimum())
+ state |= Unavailable;
+ break;
+ default:
+ break;
+ }
+ return state;
+}
+#endif // QT_NO_SPINBOX
+
+#ifndef QT_NO_SCROLLBAR
+/*!
+ \class QAccessibleScrollBar
+ \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ \enum QAccessibleScrollBar::ScrollBarElements
+
+ This enum identifies the components of the scroll bar.
+
+ \value ScrollBarSelf The scroll bar as a whole.
+ \value LineUp The up arrow button.
+ \value PageUp The area between the position and the up arrow button.
+ \value Position The position marking rectangle.
+ \value PageDown The area between the position and the down arrow button.
+ \value LineDown The down arrow button.
+*/
+
+/*!
+ Constructs a QAccessibleScrollBar object for \a w.
+ \a name is propagated to the QAccessibleWidgetEx constructor.
+*/
+QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w)
+: QAccessibleAbstractSlider(w, ScrollBar)
+{
+ Q_ASSERT(scrollBar());
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+}
+
+/*! Returns the scroll bar. */
+QScrollBar *QAccessibleScrollBar::scrollBar() const
+{
+ return qobject_cast<QScrollBar*>(object());
+}
+
+/*! \reimp */
+QRect QAccessibleScrollBar::rect(int child) const
+{
+ if (!scrollBar()->isVisible())
+ return QRect();
+
+ QStyle::SubControl subControl;
+ switch (child) {
+ case LineUp:
+ subControl = QStyle ::SC_ScrollBarSubLine;
+ break;
+ case PageUp:
+ subControl = QStyle::SC_ScrollBarSubPage;
+ break;
+ case Position:
+ subControl = QStyle::SC_ScrollBarSlider;
+ break;
+ case PageDown:
+ subControl = QStyle::SC_ScrollBarAddPage;
+ break;
+ case LineDown:
+ subControl = QStyle::SC_ScrollBarAddLine;
+ break;
+ default:
+ return QAccessibleAbstractSlider::rect(child);
+ }
+
+ const QStyleOptionSlider option = qt_qscrollbarStyleOption(scrollBar());
+ const QRect rect = scrollBar()->style()->subControlRect(QStyle::CC_ScrollBar, &option,
+ subControl, scrollBar());
+ const QPoint tp = scrollBar()->mapToGlobal(QPoint(0,0));
+ return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height());
+}
+
+/*! \reimp */
+int QAccessibleScrollBar::childCount() const
+{
+ if (!scrollBar()->isVisible())
+ return 0;
+ return LineDown;
+}
+
+/*! \reimp */
+QString QAccessibleScrollBar::text(Text t, int child) const
+{
+ if (!scrollBar()->isVisible())
+ return QString();
+ switch (t) {
+ case Value:
+ if (!child || child == Position)
+ return QString::number(scrollBar()->value());
+ return QString();
+ case Name:
+ switch (child) {
+ case LineUp:
+ return QScrollBar::tr("Line up");
+ case PageUp:
+ return QScrollBar::tr("Page up");
+ case Position:
+ return QScrollBar::tr("Position");
+ case PageDown:
+ return QScrollBar::tr("Page down");
+ case LineDown:
+ return QScrollBar::tr("Line down");
+ }
+ break;
+ default:
+ break;
+ }
+ return QAccessibleAbstractSlider::text(t, child);
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleScrollBar::role(int child) const
+{
+ switch (child) {
+ case LineUp:
+ case PageUp:
+ case PageDown:
+ case LineDown:
+ return PushButton;
+ case Position:
+ return Indicator;
+ default:
+ return ScrollBar;
+ }
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleScrollBar::state(int child) const
+{
+ const State parentState = QAccessibleAbstractSlider::state(0);
+
+ if (child == 0)
+ return parentState;
+
+ // Inherit the Invisible state from parent.
+ State state = parentState & QAccessible::Invisible;
+
+ // Disable left/right if we are at the minimum/maximum.
+ const QScrollBar * const scrollBar = QAccessibleScrollBar::scrollBar();
+ switch (child) {
+ case LineUp:
+ case PageUp:
+ if (scrollBar->value() <= scrollBar->minimum())
+ state |= Unavailable;
+ break;
+ case LineDown:
+ case PageDown:
+ if (scrollBar->value() >= scrollBar->maximum())
+ state |= Unavailable;
+ break;
+ case Position:
+ default:
+ break;
+ }
+
+ return state;
+}
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+/*!
+ \class QAccessibleSlider
+ \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ \enum QAccessibleSlider::SliderElements
+
+ This enum identifies the components of the slider.
+
+ \value SliderSelf The slider as a whole.
+ \value PageLeft The area to the left of the position.
+ \value Position The position indicator.
+ \value PageRight The area to the right of the position.
+*/
+
+/*!
+ Constructs a QAccessibleScrollBar object for \a w.
+ \a name is propagated to the QAccessibleWidgetEx constructor.
+*/
+QAccessibleSlider::QAccessibleSlider(QWidget *w)
+: QAccessibleAbstractSlider(w)
+{
+ Q_ASSERT(slider());
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+}
+
+/*! Returns the slider. */
+QSlider *QAccessibleSlider::slider() const
+{
+ return qobject_cast<QSlider*>(object());
+}
+
+/*! \reimp */
+QRect QAccessibleSlider::rect(int child) const
+{
+ QRect rect;
+ if (!slider()->isVisible())
+ return rect;
+ const QStyleOptionSlider option = qt_qsliderStyleOption(slider());
+ QRect srect = slider()->style()->subControlRect(QStyle::CC_Slider, &option,
+ QStyle::SC_SliderHandle, slider());
+
+ switch (child) {
+ case PageLeft:
+ if (slider()->orientation() == Qt::Vertical)
+ rect = QRect(0, 0, slider()->width(), srect.y());
+ else
+ rect = QRect(0, 0, srect.x(), slider()->height());
+ break;
+ case Position:
+ rect = srect;
+ break;
+ case PageRight:
+ if (slider()->orientation() == Qt::Vertical)
+ rect = QRect(0, srect.y() + srect.height(), slider()->width(), slider()->height()- srect.y() - srect.height());
+ else
+ rect = QRect(srect.x() + srect.width(), 0, slider()->width() - srect.x() - srect.width(), slider()->height());
+ break;
+ default:
+ return QAccessibleAbstractSlider::rect(child);
+ }
+
+ QPoint tp = slider()->mapToGlobal(QPoint(0,0));
+ return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height());
+}
+
+/*! \reimp */
+int QAccessibleSlider::childCount() const
+{
+ if (!slider()->isVisible())
+ return 0;
+ return PageRight;
+}
+
+/*! \reimp */
+QString QAccessibleSlider::text(Text t, int child) const
+{
+ if (!slider()->isVisible())
+ return QString();
+ switch (t) {
+ case Value:
+ if (!child || child == 2)
+ return QString::number(slider()->value());
+ return QString();
+ case Name:
+ switch (child) {
+ case PageLeft:
+ return slider()->orientation() == Qt::Horizontal ?
+ QSlider::tr("Page left") : QSlider::tr("Page up");
+ case Position:
+ return QSlider::tr("Position");
+ case PageRight:
+ return slider()->orientation() == Qt::Horizontal ?
+ QSlider::tr("Page right") : QSlider::tr("Page down");
+ }
+ break;
+ default:
+ break;
+ }
+ return QAccessibleAbstractSlider::text(t, child);
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleSlider::role(int child) const
+{
+ switch (child) {
+ case PageLeft:
+ case PageRight:
+ return PushButton;
+ case Position:
+ return Indicator;
+ default:
+ return Slider;
+ }
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleSlider::state(int child) const
+{
+ const State parentState = QAccessibleAbstractSlider::state(0);
+
+ if (child == 0)
+ return parentState;
+
+ // Inherit the Invisible state from parent.
+ State state = parentState & QAccessible::Invisible;
+
+ // Disable left/right if we are at the minimum/maximum.
+ const QSlider * const slider = QAccessibleSlider::slider();
+ switch (child) {
+ case PageLeft:
+ if (slider->value() <= slider->minimum())
+ state |= Unavailable;
+ break;
+ case PageRight:
+ if (slider->value() >= slider->maximum())
+ state |= Unavailable;
+ break;
+ case Position:
+ default:
+ break;
+ }
+
+ return state;
+}
+
+/*!
+ \fn int QAccessibleSlider::defaultAction(int child) const
+
+ Returns the default action for the given \a child. The base class
+ implementation returns 0.
+*/
+int QAccessibleSlider::defaultAction(int /*child*/) const
+{
+/*
+ switch (child) {
+ case SliderSelf:
+ return SetFocus;
+ case PageLeft:
+ return Press;
+ case PageRight:
+ return Press;
+ }
+*/
+ return 0;
+}
+
+/*! \internal */
+QString QAccessibleSlider::actionText(int /*action*/, Text /*t*/, int /*child*/) const
+{
+ return QLatin1String("");
+}
+
+QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, Role r)
+ : QAccessibleWidgetEx(w, r)
+{
+ Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
+}
+
+QVariant QAccessibleAbstractSlider::invokeMethodEx(Method method, int child, const QVariantList &params)
+{
+ switch (method) {
+ case ListSupportedMethods: {
+ QSet<QAccessible::Method> set;
+ set << ListSupportedMethods;
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
+ }
+ default:
+ return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
+ }
+}
+
+QVariant QAccessibleAbstractSlider::currentValue()
+{
+ return abstractSlider()->value();
+}
+
+void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value)
+{
+ abstractSlider()->setValue(value.toInt());
+}
+
+QVariant QAccessibleAbstractSlider::maximumValue()
+{
+ return abstractSlider()->maximum();
+}
+
+QVariant QAccessibleAbstractSlider::minimumValue()
+{
+ return abstractSlider()->minimum();
+}
+
+QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const
+{
+ return static_cast<QAbstractSlider *>(object());
+}
+
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_DIAL
+// ======================================= QAccessibleDial ======================================
+QAccessibleDial::QAccessibleDial(QWidget *widget)
+ : QAccessibleWidgetEx(widget, Dial)
+{
+ Q_ASSERT(qobject_cast<QDial *>(widget));
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+}
+
+QRect QAccessibleDial::rect(int child) const
+{
+ QRect rect;
+ if (!dial()->isVisible())
+ return rect;
+ switch (child) {
+ case Self:
+ return QAccessibleWidgetEx::rect(child);
+ case SpeedoMeter: {
+ // Mixture from qcommonstyle.cpp (focus rect).
+ int width = dial()->width();
+ int height = dial()->height();
+ qreal radius = qMin(width, height) / 2.0;
+ qreal delta = radius / 6.0;
+ qreal dx = delta + (width - 2 * radius) / 2.0;
+ qreal dy = delta + (height - 2 * radius) / 2.0;
+ rect = QRect(int(dx), int(dy), int(radius * 2 - 2 * delta), int(radius * 2 - 2 * delta));
+ if (dial()->notchesVisible()) {
+ rect.translate(int(-radius / 6), int(-radius / 6));
+ rect.setWidth(rect.width() + int(radius / 3));
+ rect.setHeight(rect.height() + int(radius / 3));
+ }
+ break;
+ }
+ case SliderHandle: {
+ // Mixture from qcommonstyle.cpp and qdial.cpp.
+ int sliderValue = !dial()->invertedAppearance() ? dial()->value()
+ : (dial()->maximum() - dial()->value());
+ qreal angle = 0;
+ if (dial()->maximum() == dial()->minimum()) {
+ angle = Q_PI / 2;
+ } else if (dial()->wrapping()) {
+ angle = Q_PI * 3 / 2 - (sliderValue - dial()->minimum()) * 2 * Q_PI
+ / (dial()->maximum() - dial()->minimum());
+ } else {
+ angle = (Q_PI * 8 - (sliderValue - dial()->minimum()) * 10 * Q_PI
+ / (dial()->maximum() - dial()->minimum())) / 6;
+ }
+
+ int width = dial()->rect().width();
+ int height = dial()->rect().height();
+ int radius = qMin(width, height) / 2;
+ int xc = width / 2;
+ int yc = height / 2;
+ int bigLineSize = radius / 6;
+ if (bigLineSize < 4)
+ bigLineSize = 4;
+ if (bigLineSize > radius / 2)
+ bigLineSize = radius / 2;
+ int len = radius - bigLineSize - 5;
+ if (len < 5)
+ len = 5;
+ int back = len / 2;
+
+ QPolygonF arrow(3);
+ arrow[0] = QPointF(0.5 + xc + len * qCos(angle),
+ 0.5 + yc - len * qSin(angle));
+ arrow[1] = QPointF(0.5 + xc + back * qCos(angle + Q_PI * 5 / 6),
+ 0.5 + yc - back * qSin(angle + Q_PI * 5 / 6));
+ arrow[2] = QPointF(0.5 + xc + back * qCos(angle - Q_PI * 5 / 6),
+ 0.5 + yc - back * qSin(angle - Q_PI * 5 / 6));
+ rect = arrow.boundingRect().toRect();
+ break;
+ }
+ default:
+ return QRect();
+ }
+
+ QPoint globalPos = dial()->mapToGlobal(QPoint(0,0));
+ return QRect(globalPos.x() + rect.x(), globalPos.y() + rect.y(), rect.width(), rect.height());
+}
+
+int QAccessibleDial::childCount() const
+{
+ if (!dial()->isVisible())
+ return 0;
+ return SliderHandle;
+}
+
+QString QAccessibleDial::text(Text textType, int child) const
+{
+ if (!dial()->isVisible())
+ return QString();
+ if (textType == Value && child >= Self && child <= SliderHandle)
+ return QString::number(dial()->value());
+ if (textType == Name) {
+ switch (child) {
+ case Self:
+ if (!widget()->accessibleName().isEmpty())
+ return widget()->accessibleName();
+ return QDial::tr("QDial");
+ case SpeedoMeter:
+ return QDial::tr("SpeedoMeter");
+ case SliderHandle:
+ return QDial::tr("SliderHandle");
+ }
+ }
+ return QAccessibleWidgetEx::text(textType, child);
+}
+
+QAccessible::Role QAccessibleDial::role(int child) const
+{
+ if (child == SpeedoMeter)
+ return Slider;
+ else if (child == SliderHandle)
+ return Indicator;
+ return QAccessibleWidgetEx::role(child);
+}
+
+QAccessible::State QAccessibleDial::state(int child) const
+{
+ const State parentState = QAccessibleWidgetEx::state(0);
+ if (child == SliderHandle)
+ return parentState | HotTracked;
+ return parentState;
+}
+
+QVariant QAccessibleDial::invokeMethodEx(Method, int, const QVariantList &)
+{
+ return QVariant();
+}
+
+QDial *QAccessibleDial::dial() const
+{
+ return static_cast<QDial*>(object());
+}
+#endif // QT_NO_DIAL
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
diff --git a/src/plugins/accessible/widgets/rangecontrols.h b/src/plugins/accessible/widgets/rangecontrols.h
new file mode 100644
index 0000000000..f565d8e888
--- /dev/null
+++ b/src/plugins/accessible/widgets/rangecontrols.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RANGECONTROLS_H
+#define RANGECONTROLS_H
+
+#include <QtGui/qaccessiblewidget.h>
+#include <QtGui/qaccessible2.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAbstractSpinBox;
+class QAbstractSlider;
+class QScrollBar;
+class QSlider;
+class QSpinBox;
+class QDoubleSpinBox;
+class QDial;
+
+#ifndef QT_NO_SPINBOX
+class QAccessibleAbstractSpinBox: public QAccessibleWidgetEx, public QAccessibleValueInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleAbstractSpinBox(QWidget *w);
+
+ enum SpinBoxElements {
+ SpinBoxSelf = 0,
+ Editor,
+ ValueUp,
+ ValueDown
+ };
+
+ int childCount() const;
+ QRect rect(int child) const;
+
+ int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
+
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+
+ bool doAction(int action, int child, const QVariantList &params);
+
+ QVariant invokeMethodEx(Method method, int child, const QVariantList &params);
+
+ // QAccessibleValueInterface
+ QVariant currentValue();
+ void setCurrentValue(const QVariant &value);
+ QVariant maximumValue();
+ QVariant minimumValue();
+
+protected:
+ QAbstractSpinBox *abstractSpinBox() const;
+};
+
+class QAccessibleSpinBox : public QAccessibleAbstractSpinBox
+{
+public:
+ explicit QAccessibleSpinBox(QWidget *w);
+
+ State state(int child) const;
+
+ bool doAction(int action, int child, const QVariantList &params);
+
+protected:
+ QSpinBox *spinBox() const;
+};
+
+class QAccessibleDoubleSpinBox : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleDoubleSpinBox(QWidget *widget);
+
+ enum DoubleSpinBoxElements {
+ SpinBoxSelf = 0,
+ Editor,
+ ValueUp,
+ ValueDown
+ };
+
+ int childCount() const;
+ QRect rect(int child) const;
+ int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+protected:
+ QDoubleSpinBox *doubleSpinBox() const;
+};
+#endif // QT_NO_SPINBOX
+
+class QAccessibleAbstractSlider: public QAccessibleWidgetEx, public QAccessibleValueInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleAbstractSlider(QWidget *w, Role r = Slider);
+
+ QVariant invokeMethodEx(Method method, int child, const QVariantList &params);
+
+ // QAccessibleValueInterface
+ QVariant currentValue();
+ void setCurrentValue(const QVariant &value);
+ QVariant maximumValue();
+ QVariant minimumValue();
+
+protected:
+ QAbstractSlider *abstractSlider() const;
+};
+
+#ifndef QT_NO_SCROLLBAR
+class QAccessibleScrollBar : public QAccessibleAbstractSlider
+{
+public:
+ explicit QAccessibleScrollBar(QWidget *w);
+
+ enum ScrollBarElements {
+ ScrollBarSelf = 0,
+ LineUp,
+ PageUp,
+ Position,
+ PageDown,
+ LineDown
+ };
+
+ int childCount() const;
+
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+protected:
+ QScrollBar *scrollBar() const;
+};
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+class QAccessibleSlider : public QAccessibleAbstractSlider
+{
+public:
+ explicit QAccessibleSlider(QWidget *w);
+
+ enum SliderElements {
+ SliderSelf = 0,
+ PageLeft,
+ Position,
+ PageRight
+ };
+
+ int childCount() const;
+
+ QRect rect(int child) const;
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+ int defaultAction(int child) const;
+ QString actionText(int action, Text t, int child) const;
+
+protected:
+ QSlider *slider() const;
+};
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_DIAL
+class QAccessibleDial : public QAccessibleWidgetEx
+{
+public:
+ explicit QAccessibleDial(QWidget *w);
+
+ enum DialElements {
+ Self = 0,
+ SpeedoMeter,
+ SliderHandle
+ };
+
+ int childCount() const;
+ QRect rect(int child) const;
+ QString text(Text textType, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+ QVariant invokeMethodEx(Method method, int child, const QVariantList &params);
+
+protected:
+ QDial *dial() const;
+};
+#endif // QT_NO_DIAL
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // RANGECONTROLS_H
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
new file mode 100644
index 0000000000..21d2d671f3
--- /dev/null
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -0,0 +1,888 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "simplewidgets.h"
+
+#include <qabstractbutton.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qprogressbar.h>
+#include <qradiobutton.h>
+#include <qtoolbutton.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+#include <qlcdnumber.h>
+#include <qlineedit.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+
+#ifdef Q_OS_MAC
+#include <qfocusframe.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+using namespace QAccessible2;
+extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel = false);
+
+QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
+QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
+
+/*!
+ \class QAccessibleButton
+ \brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Creates a QAccessibleButton object for \a w.
+ \a role is propagated to the QAccessibleWidgetEx constructor.
+*/
+QAccessibleButton::QAccessibleButton(QWidget *w, Role role)
+: QAccessibleWidgetEx(w, role)
+{
+ Q_ASSERT(button());
+ if (button()->isCheckable())
+ addControllingSignal(QLatin1String("toggled(bool)"));
+ else
+ addControllingSignal(QLatin1String("clicked()"));
+}
+
+/*! Returns the button. */
+QAbstractButton *QAccessibleButton::button() const
+{
+ return qobject_cast<QAbstractButton*>(object());
+}
+
+/*! \reimp */
+QString QAccessibleButton::actionText(int action, Text text, int child) const
+{
+ if (child)
+ return QString();
+
+ if (text == Name) switch (action) {
+ case Press:
+ case DefaultAction: // press, checking or open
+ switch (role(0)) {
+ case ButtonMenu:
+ return QPushButton::tr("Open");
+ case CheckBox:
+ {
+ if (state(child) & Checked)
+ return QCheckBox::tr("Uncheck");
+ QCheckBox *cb = qobject_cast<QCheckBox*>(object());
+ if (!cb || !cb->isTristate() || cb->checkState() == Qt::PartiallyChecked)
+ return QCheckBox::tr("Check");
+ return QCheckBox::tr("Toggle");
+ }
+ break;
+ case RadioButton:
+ return QRadioButton::tr("Check");
+ default:
+ break;
+ }
+ break;
+ }
+ return QAccessibleWidgetEx::actionText(action, text, child);
+}
+
+/*! \reimp */
+bool QAccessibleButton::doAction(int action, int child, const QVariantList &params)
+{
+ if (child || !widget()->isEnabled() || !widget()->isVisible())
+ return false;
+
+ switch (action) {
+ case DefaultAction:
+ case Press:
+ {
+#ifndef QT_NO_MENU
+ QPushButton *pb = qobject_cast<QPushButton*>(object());
+ if (pb && pb->menu())
+ pb->showMenu();
+ else
+#endif
+ button()->animateClick();
+ }
+ return true;
+ }
+ return QAccessibleWidgetEx::doAction(action, child, params);
+}
+
+/*! \reimp */
+QString QAccessibleButton::text(Text t, int child) const
+{
+ QString str;
+ if (!widget()->isVisible())
+ return str;
+
+ switch (t) {
+ case Accelerator:
+ {
+#ifndef QT_NO_SHORTCUT
+ QPushButton *pb = qobject_cast<QPushButton*>(object());
+ if (pb && pb->isDefault())
+ str = (QString)QKeySequence(Qt::Key_Enter);
+#endif
+ if (str.isEmpty())
+ str = qt_accHotKey(button()->text());
+ }
+ break;
+ case Name:
+ str = widget()->accessibleName();
+ if (str.isEmpty())
+ str = button()->text();
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, child);;
+ return qt_accStripAmp(str);
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleButton::state(int child) const
+{
+ State state = QAccessibleWidgetEx::state(child);
+
+ QAbstractButton *b = button();
+ QCheckBox *cb = qobject_cast<QCheckBox *>(b);
+ if (b->isChecked())
+ state |= Checked;
+ else if (cb && cb->checkState() == Qt::PartiallyChecked)
+ state |= Mixed;
+ if (b->isDown())
+ state |= Pressed;
+ QPushButton *pb = qobject_cast<QPushButton*>(b);
+ if (pb) {
+ if (pb->isDefault())
+ state |= DefaultButton;
+#ifndef QT_NO_MENU
+ if (pb->menu())
+ state |= HasPopup;
+#endif
+ }
+
+ return state;
+}
+
+int QAccessibleButton::actionCount()
+{
+ return 1;
+}
+
+void QAccessibleButton::doAction(int actionIndex)
+{
+ switch (actionIndex) {
+ case 0:
+ button()->click();
+ break;
+ }
+}
+
+QString QAccessibleButton::description(int actionIndex)
+{
+ switch (actionIndex) {
+ case 0:
+ return QLatin1String("Clicks the button.");
+ default:
+ return QString();
+ }
+}
+
+QString QAccessibleButton::name(int actionIndex)
+{
+ switch (actionIndex) {
+ case 0:
+ return QLatin1String("Press");
+ default:
+ return QString();
+ }
+}
+
+QString QAccessibleButton::localizedName(int actionIndex)
+{
+ switch (actionIndex) {
+ case 0:
+ return tr("Press");
+ default:
+ return QString();
+ }
+}
+
+QStringList QAccessibleButton::keyBindings(int actionIndex)
+{
+ switch (actionIndex) {
+#ifndef QT_NO_SHORTCUT
+ case 0:
+ return QStringList() << button()->shortcut().toString();
+#endif
+ default:
+ return QStringList();
+ }
+}
+
+#ifndef QT_NO_TOOLBUTTON
+/*!
+ \class QAccessibleToolButton
+ \brief The QAccessibleToolButton class implements the QAccessibleInterface for tool buttons.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ \enum QAccessibleToolButton::ToolButtonElements
+
+ This enum identifies the components of the tool button.
+
+ \value ToolButtonSelf The tool button as a whole.
+ \value ButtonExecute The button.
+ \value ButtonDropMenu The drop down menu.
+*/
+
+/*!
+ Creates a QAccessibleToolButton object for \a w.
+ \a role is propagated to the QAccessibleWidgetEx constructor.
+*/
+QAccessibleToolButton::QAccessibleToolButton(QWidget *w, Role role)
+: QAccessibleButton(w, role)
+{
+ Q_ASSERT(toolButton());
+}
+
+/*! Returns the button. */
+QToolButton *QAccessibleToolButton::toolButton() const
+{
+ return qobject_cast<QToolButton*>(object());
+}
+
+/*!
+ Returns true if this tool button is a split button.
+*/
+bool QAccessibleToolButton::isSplitButton() const
+{
+#ifndef QT_NO_MENU
+ return toolButton()->menu() && toolButton()->popupMode() == QToolButton::MenuButtonPopup;
+#else
+ return false;
+#endif
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleToolButton::role(int child) const
+{
+ if (isSplitButton()) switch(child) {
+ case ButtonExecute:
+ return PushButton;
+ case ButtonDropMenu:
+ return ButtonMenu;
+ }
+ return QAccessibleButton::role(child);
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleToolButton::state(int child) const
+{
+ QAccessible::State st = QAccessibleButton::state(child);
+ if (toolButton()->autoRaise())
+ st |= HotTracked;
+#ifndef QT_NO_MENU
+ if (toolButton()->menu() && child != ButtonExecute)
+ st |= HasPopup;
+#endif
+ return st;
+}
+
+/*! \reimp */
+int QAccessibleToolButton::childCount() const
+{
+ if (!toolButton()->isVisible())
+ return 0;
+ return isSplitButton() ? ButtonDropMenu : 0;
+}
+
+/*!
+ \internal
+
+ Returns the rectangle occupied by this button, depending on \a
+ child.
+*/
+QRect QAccessibleToolButton::rect(int child) const
+{
+ if (!toolButton()->isVisible())
+ return QRect();
+ if (!child)
+ return QAccessibleButton::rect(child);
+
+ QStyleOptionToolButton opt;
+ opt.init(widget());
+ QRect subrect = widget()->style()->subControlRect(QStyle::CC_ToolButton, &opt,
+ QStyle::SC_ToolButtonMenu, toolButton());
+
+ if (child == ButtonExecute)
+ subrect = QRect(0, 0, subrect.x(), widget()->height());
+
+ QPoint ntl = widget()->mapToGlobal(subrect.topLeft());
+ subrect.moveTopLeft(ntl);
+ return subrect;
+}
+
+/*!
+ \internal
+
+ Returns the button's text label, depending on the text \a t, and
+ the \a child.
+*/
+QString QAccessibleToolButton::text(Text t, int child) const
+{
+ QString str;
+ if (!toolButton()->isVisible())
+ return str;
+
+ switch (t) {
+ case Name:
+ str = toolButton()->text();
+ if (str.isEmpty())
+ str = toolButton()->text();
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleButton::text(t, child);;
+ return qt_accStripAmp(str);
+}
+
+/*!
+ \internal
+
+ Returns the number of actions which is 0, 1, or 2, in part
+ depending on \a child.
+*/
+int QAccessibleToolButton::actionCount(int child) const
+{
+ // each subelement has one action
+ if (child)
+ return isSplitButton() ? 1 : 0;
+ int ac = widget()->focusPolicy() != Qt::NoFocus ? 1 : 0;
+ // button itself has two actions if a menu button
+#ifndef QT_NO_MENU
+ return ac + (toolButton()->menu() ? 2 : 1);
+#else
+ return ac + 1;
+#endif
+}
+
+/*!
+ \internal
+
+ If \a text is \c Name, then depending on the \a child or the \a
+ action, an action text is returned. This is a translated string
+ which in English is one of "Press", "Open", or "Set Focus". If \a
+ text is not \c Name, an empty string is returned.
+*/
+QString QAccessibleToolButton::actionText(int action, Text text, int child) const
+{
+ if (text == Name) switch(child) {
+ case ButtonExecute:
+ return QToolButton::tr("Press");
+ case ButtonDropMenu:
+ return QToolButton::tr("Open");
+ default:
+ switch(action) {
+ case 0:
+ return QToolButton::tr("Press");
+ case 1:
+#ifndef QT_NO_MENU
+ if (toolButton()->menu())
+ return QToolButton::tr("Open");
+#endif
+ //fall through
+ case 2:
+ return QLatin1String("Set Focus");
+ }
+ }
+ return QString();
+}
+
+/*!
+ \internal
+*/
+bool QAccessibleToolButton::doAction(int action, int child, const QVariantList &params)
+{
+ if (!widget()->isEnabled() || !widget()->isVisible())
+ return false;
+ if (action == 1 || child == ButtonDropMenu) {
+ if(!child)
+ toolButton()->setDown(true);
+#ifndef QT_NO_MENU
+ toolButton()->showMenu();
+#endif
+ return true;
+ }
+ return QAccessibleButton::doAction(action, 0, params);
+}
+
+#endif // QT_NO_TOOLBUTTON
+
+/*!
+ \class QAccessibleDisplay
+ \brief The QAccessibleDisplay class implements the QAccessibleInterface for widgets that display information.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleDisplay object for \a w.
+ \a role is propagated to the QAccessibleWidgetEx constructor.
+*/
+QAccessibleDisplay::QAccessibleDisplay(QWidget *w, Role role)
+: QAccessibleWidgetEx(w, role)
+{
+}
+
+/*! \reimp */
+QAccessible::Role QAccessibleDisplay::role(int child) const
+{
+ QLabel *l = qobject_cast<QLabel*>(object());
+ if (l) {
+ if (l->pixmap())
+ return Graphic;
+#ifndef QT_NO_PICTURE
+ if (l->picture())
+ return Graphic;
+#endif
+#ifndef QT_NO_MOVIE
+ if (l->movie())
+ return Animation;
+#endif
+#ifndef QT_NO_PROGRESSBAR
+ } else if (qobject_cast<QProgressBar*>(object())) {
+ return ProgressBar;
+#endif
+ }
+ return QAccessibleWidgetEx::role(child);
+}
+
+/*! \reimp */
+QString QAccessibleDisplay::text(Text t, int child) const
+{
+ QString str;
+ if (!widget()->isVisible())
+ return str;
+ switch (t) {
+ case Name:
+ str = widget()->accessibleName();
+ if (str.isEmpty()) {
+ if (qobject_cast<QLabel*>(object())) {
+ str = qobject_cast<QLabel*>(object())->text();
+#ifndef QT_NO_GROUPBOX
+ } else if (qobject_cast<QGroupBox*>(object())) {
+ str = qobject_cast<QGroupBox*>(object())->title();
+#endif
+#ifndef QT_NO_LCDNUMBER
+ } else if (qobject_cast<QLCDNumber*>(object())) {
+ QLCDNumber *l = qobject_cast<QLCDNumber*>(object());
+ if (l->digitCount())
+ str = QString::number(l->value());
+ else
+ str = QString::number(l->intValue());
+#endif
+ }
+ }
+ break;
+ case Value:
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar*>(object()))
+ str = QString::number(qobject_cast<QProgressBar*>(object())->value());
+#endif
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, child);;
+ return qt_accStripAmp(str);
+}
+
+/*! \reimp */
+QAccessible::Relation QAccessibleDisplay::relationTo(int child, const QAccessibleInterface *other,
+ int otherChild) const
+{
+ Relation relation = QAccessibleWidgetEx::relationTo(child, other, otherChild);
+ if (child || otherChild)
+ return relation;
+
+ QObject *o = other->object();
+ QLabel *label = qobject_cast<QLabel*>(object());
+ if (label) {
+#ifndef QT_NO_SHORTCUT
+ if (o == label->buddy())
+ relation |= Label;
+#endif
+#ifndef QT_NO_GROUPBOX
+ } else {
+ QGroupBox *groupbox = qobject_cast<QGroupBox*>(object());
+ if (groupbox && !groupbox->title().isEmpty())
+ if (groupbox->children().contains(o))
+ relation |= Label;
+#endif
+ }
+ return relation;
+}
+
+/*! \reimp */
+int QAccessibleDisplay::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
+{
+ *target = 0;
+ if (rel == Labelled) {
+ QObject *targetObject = 0;
+ QLabel *label = qobject_cast<QLabel*>(object());
+ if (label) {
+#ifndef QT_NO_SHORTCUT
+ if (entry == 1)
+ targetObject = label->buddy();
+#endif
+#ifndef QT_NO_GROUPBOX
+ } else {
+ QGroupBox *groupbox = qobject_cast<QGroupBox*>(object());
+ if (groupbox && !groupbox->title().isEmpty())
+ rel = Child;
+#endif
+ }
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ if (*target)
+ return 0;
+ }
+ return QAccessibleWidgetEx::navigate(rel, entry, target);
+}
+
+/*! \internal */
+QString QAccessibleDisplay::imageDescription()
+{
+#ifndef QT_NO_TOOLTIP
+ return widget()->toolTip();
+#else
+ return QString::null;
+#endif
+}
+
+/*! \internal */
+QSize QAccessibleDisplay::imageSize()
+{
+ QLabel *label = qobject_cast<QLabel *>(widget());
+ if (!label)
+ return QSize();
+ const QPixmap *pixmap = label->pixmap();
+ if (!pixmap)
+ return QSize();
+ return pixmap->size();
+}
+
+/*! \internal */
+QRect QAccessibleDisplay::imagePosition(QAccessible2::CoordinateType coordType)
+{
+ QLabel *label = qobject_cast<QLabel *>(widget());
+ if (!label)
+ return QRect();
+ const QPixmap *pixmap = label->pixmap();
+ if (!pixmap)
+ return QRect();
+
+ switch (coordType) {
+ case QAccessible2::RelativeToScreen:
+ return QRect(label->mapToGlobal(label->pos()), label->size());
+ case QAccessible2::RelativeToParent:
+ return label->geometry();
+ }
+
+ return QRect();
+}
+
+#ifndef QT_NO_LINEEDIT
+/*!
+ \class QAccessibleLineEdit
+ \brief The QAccessibleLineEdit class implements the QAccessibleInterface for widgets with editable text
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleLineEdit object for \a w.
+ \a name is propagated to the QAccessibleWidgetEx constructor.
+*/
+QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name)
+: QAccessibleWidgetEx(w, EditableText, name), QAccessibleSimpleEditableTextInterface(this)
+{
+ addControllingSignal(QLatin1String("textChanged(const QString&)"));
+ addControllingSignal(QLatin1String("returnPressed()"));
+}
+
+/*! Returns the line edit. */
+QLineEdit *QAccessibleLineEdit::lineEdit() const
+{
+ return qobject_cast<QLineEdit*>(object());
+}
+
+/*! \reimp */
+QString QAccessibleLineEdit::text(Text t, int child) const
+{
+ QString str;
+ if (!lineEdit()->isVisible())
+ return str;
+ switch (t) {
+ case Value:
+ if (lineEdit()->echoMode() == QLineEdit::Normal)
+ str = lineEdit()->text();
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidgetEx::text(t, child);;
+ return qt_accStripAmp(str);
+}
+
+/*! \reimp */
+void QAccessibleLineEdit::setText(Text t, int control, const QString &text)
+{
+ if (!lineEdit()->isVisible())
+ return;
+ if (t != Value || control) {
+ QAccessibleWidgetEx::setText(t, control, text);
+ return;
+ }
+ lineEdit()->setText(text);
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleLineEdit::state(int child) const
+{
+ State state = QAccessibleWidgetEx::state(child);
+
+ QLineEdit *l = lineEdit();
+ if (l->isReadOnly())
+ state |= ReadOnly;
+ if (l->echoMode() != QLineEdit::Normal)
+ state |= Protected;
+ state |= Selectable;
+ if (l->hasSelectedText())
+ state |= Selected;
+
+ if (l->contextMenuPolicy() != Qt::NoContextMenu
+ && l->contextMenuPolicy() != Qt::PreventContextMenu)
+ state |= HasPopup;
+
+ return state;
+}
+
+QVariant QAccessibleLineEdit::invokeMethodEx(QAccessible::Method method, int child,
+ const QVariantList &params)
+{
+ if (child)
+ return QVariant();
+
+ switch (method) {
+ case ListSupportedMethods: {
+ QSet<QAccessible::Method> set;
+ set << ListSupportedMethods << SetCursorPosition << GetCursorPosition;
+ return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
+ QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
+ }
+ case SetCursorPosition:
+ setCursorPosition(params.value(0).toInt());
+ return true;
+ case GetCursorPosition:
+ return cursorPosition();
+ default:
+ return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
+ }
+}
+
+void QAccessibleLineEdit::addSelection(int startOffset, int endOffset)
+{
+ setSelection(0, startOffset, endOffset);
+}
+
+QString QAccessibleLineEdit::attributes(int offset, int *startOffset, int *endOffset)
+{
+ // QLineEdit doesn't have text attributes
+ *startOffset = *endOffset = offset;
+ return QString();
+}
+
+int QAccessibleLineEdit::cursorPosition()
+{
+ return lineEdit()->cursorPosition();
+}
+
+QRect QAccessibleLineEdit::characterRect(int /*offset*/, CoordinateType /*coordType*/)
+{
+ // QLineEdit doesn't hand out character rects
+ return QRect();
+}
+
+int QAccessibleLineEdit::selectionCount()
+{
+ return lineEdit()->hasSelectedText() ? 1 : 0;
+}
+
+int QAccessibleLineEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType)
+{
+ QPoint p = point;
+ if (coordType == RelativeToScreen)
+ p = lineEdit()->mapFromGlobal(p);
+
+ return lineEdit()->cursorPositionAt(p);
+}
+
+void QAccessibleLineEdit::selection(int selectionIndex, int *startOffset, int *endOffset)
+{
+ *startOffset = *endOffset = 0;
+ if (selectionIndex != 0)
+ return;
+
+ *startOffset = lineEdit()->selectionStart();
+ *endOffset = *startOffset + lineEdit()->selectedText().count();
+}
+
+QString QAccessibleLineEdit::text(int startOffset, int endOffset)
+{
+ if (startOffset > endOffset)
+ return QString();
+ return lineEdit()->text().mid(startOffset, endOffset - startOffset);
+}
+
+QString QAccessibleLineEdit::textBeforeOffset (int /*offset*/, BoundaryType /*boundaryType*/,
+ int * /*startOffset*/, int * /*endOffset*/)
+{
+ // TODO
+ return QString();
+}
+
+QString QAccessibleLineEdit::textAfterOffset(int /*offset*/, BoundaryType /*boundaryType*/,
+ int * /*startOffset*/, int * /*endOffset*/)
+{
+ // TODO
+ return QString();
+}
+
+QString QAccessibleLineEdit::textAtOffset(int /*offset*/, BoundaryType /*boundaryType*/,
+ int * /*startOffset*/, int * /*endOffset*/)
+{
+ // TODO
+ return QString();
+}
+
+void QAccessibleLineEdit::removeSelection(int selectionIndex)
+{
+ if (selectionIndex != 0)
+ return;
+
+ lineEdit()->deselect();
+}
+
+void QAccessibleLineEdit::setCursorPosition(int position)
+{
+ lineEdit()->setCursorPosition(position);
+}
+
+void QAccessibleLineEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
+{
+ if (selectionIndex != 0)
+ return;
+
+ lineEdit()->setSelection(startOffset, endOffset - startOffset);
+}
+
+int QAccessibleLineEdit::characterCount()
+{
+ return lineEdit()->text().count();
+}
+
+void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex)
+{
+ lineEdit()->setCursorPosition(endIndex);
+ lineEdit()->setCursorPosition(startIndex);
+}
+
+#endif // QT_NO_LINEEDIT
+
+#ifndef QT_NO_PROGRESSBAR
+QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o)
+ : QAccessibleDisplay(o)
+{
+ Q_ASSERT(progressBar());
+}
+
+QVariant QAccessibleProgressBar::currentValue()
+{
+ return progressBar()->value();
+}
+
+QVariant QAccessibleProgressBar::maximumValue()
+{
+ return progressBar()->maximum();
+}
+
+QVariant QAccessibleProgressBar::minimumValue()
+{
+ return progressBar()->minimum();
+}
+
+QProgressBar *QAccessibleProgressBar::progressBar() const
+{
+ return qobject_cast<QProgressBar *>(object());
+}
+#endif
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
new file mode 100644
index 0000000000..ca1f24bfc2
--- /dev/null
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** 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$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIMPLEWIDGETS_H
+#define SIMPLEWIDGETS_H
+
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/qaccessible2.h>
+#include <QtGui/qaccessiblewidget.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAbstractButton;
+class QLineEdit;
+class QToolButton;
+class QProgressBar;
+
+class QAccessibleButton : public QAccessibleWidgetEx, public QAccessibleActionInterface
+{
+ Q_ACCESSIBLE_OBJECT
+ Q_DECLARE_TR_FUNCTIONS(QAccessibleButton)
+public:
+ QAccessibleButton(QWidget *w, Role r);
+
+ QString text(Text t, int child) const;
+ State state(int child) const;
+
+ QString actionText(int action, Text text, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+
+ // QAccessibleActionInterface
+ int actionCount();
+ void doAction(int actionIndex);
+ QString description(int actionIndex);
+ QString name(int actionIndex);
+ QString localizedName(int actionIndex);
+ QStringList keyBindings(int actionIndex);
+
+protected:
+ QAbstractButton *button() const;
+};
+
+#ifndef QT_NO_TOOLBUTTON
+class QAccessibleToolButton : public QAccessibleButton
+{
+public:
+ QAccessibleToolButton(QWidget *w, Role role);
+
+ enum ToolButtonElements {
+ ToolButtonSelf = 0,
+ ButtonExecute,
+ ButtonDropMenu
+ };
+
+ Role role(int child) const;
+ State state(int child) const;
+
+ int childCount() const;
+ QRect rect(int child) const;
+
+ QString text(Text t, int child) const;
+
+ int actionCount(int child) const;
+ QString actionText(int action, Text text, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+
+protected:
+ QToolButton *toolButton() const;
+
+ bool isSplitButton() const;
+};
+#endif // QT_NO_TOOLBUTTON
+
+class QAccessibleDisplay : public QAccessibleWidgetEx, public QAccessibleImageInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleDisplay(QWidget *w, Role role = StaticText);
+
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+ int navigate(RelationFlag, int entry, QAccessibleInterface **target) const;
+
+ // QAccessibleImageInterface
+ QString imageDescription();
+ QSize imageSize();
+ QRect imagePosition(QAccessible2::CoordinateType coordType);
+};
+
+#ifndef QT_NO_LINEEDIT
+class QAccessibleLineEdit : public QAccessibleWidgetEx, public QAccessibleTextInterface,
+ public QAccessibleSimpleEditableTextInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString());
+
+ QString text(Text t, int child) const;
+ void setText(Text t, int control, const QString &text);
+ State state(int child) const;
+ QVariant invokeMethodEx(QAccessible::Method method, int child, const QVariantList &params);
+
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset);
+ QString attributes(int offset, int *startOffset, int *endOffset);
+ int cursorPosition();
+ QRect characterRect(int offset, QAccessible2::CoordinateType coordType);
+ int selectionCount();
+ int offsetAtPoint(const QPoint &point, QAccessible2::CoordinateType coordType);
+ void selection(int selectionIndex, int *startOffset, int *endOffset);
+ QString text(int startOffset, int endOffset);
+ QString textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+ QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+ QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+ void removeSelection(int selectionIndex);
+ void setCursorPosition(int position);
+ void setSelection(int selectionIndex, int startOffset, int endOffset);
+ int characterCount();
+ void scrollToSubstring(int startIndex, int endIndex);
+
+protected:
+ QLineEdit *lineEdit() const;
+};
+#endif // QT_NO_LINEEDIT
+
+#ifndef QT_NO_PROGRESSBAR
+class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleProgressBar(QWidget *o);
+
+ // QAccessibleValueInterface
+ QVariant currentValue();
+ QVariant maximumValue();
+ QVariant minimumValue();
+ inline void setCurrentValue(const QVariant &) {}
+
+protected:
+ QProgressBar *progressBar() const;
+};
+#endif
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // SIMPLEWIDGETS_H
diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro
new file mode 100644
index 0000000000..79110cbcd4
--- /dev/null
+++ b/src/plugins/accessible/widgets/widgets.pro
@@ -0,0 +1,20 @@
+TARGET = qtaccessiblewidgets
+include(../../qpluginbase.pri)
+include (../qaccessiblebase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/accessible
+
+QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)"
+
+SOURCES += main.cpp \
+ simplewidgets.cpp \
+ rangecontrols.cpp \
+ complexwidgets.cpp \
+ qaccessiblewidgets.cpp \
+ qaccessiblemenu.cpp
+
+HEADERS += qaccessiblewidgets.h \
+ simplewidgets.h \
+ rangecontrols.h \
+ complexwidgets.h \
+ qaccessiblemenu.h