From eaee2bd0d048367f6bd331fdb4a177004848d77e Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 5 Feb 2014 11:44:42 +0100 Subject: Accessibility: Use factory function instead of plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies deployment and makes instantiating accessible interfaces faster since no plugin needs to be loaded. [ChangeLog][QtWidgets] Accessibility for widgets is now included in the widget library instead of being a separate plugin. For static builds this means that libqtaccessiblewidgets is no longer required. Task-number: QTBUG-32888 Change-Id: Ie7347898868fd67c1fc568f0d251cbd2ef71e041 Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/accessible.pro | 5 - src/plugins/accessible/widgets/complexwidgets.cpp | 459 -------- src/plugins/accessible/widgets/complexwidgets.h | 145 --- src/plugins/accessible/widgets/itemviews.cpp | 1222 -------------------- src/plugins/accessible/widgets/itemviews.h | 292 ----- src/plugins/accessible/widgets/main.cpp | 262 ----- src/plugins/accessible/widgets/qaccessiblemenu.cpp | 377 ------ src/plugins/accessible/widgets/qaccessiblemenu.h | 131 --- .../accessible/widgets/qaccessiblewidgets.cpp | 1020 ---------------- .../accessible/widgets/qaccessiblewidgets.h | 314 ----- src/plugins/accessible/widgets/rangecontrols.cpp | 323 ------ src/plugins/accessible/widgets/rangecontrols.h | 160 --- src/plugins/accessible/widgets/simplewidgets.cpp | 886 -------------- src/plugins/accessible/widgets/simplewidgets.h | 215 ---- src/plugins/accessible/widgets/widgets.json | 54 - src/plugins/accessible/widgets/widgets.pro | 26 - src/plugins/plugins.pro | 1 - src/widgets/accessible/accessible.pri | 21 +- src/widgets/accessible/complexwidgets.cpp | 459 ++++++++ src/widgets/accessible/complexwidgets.h | 145 +++ src/widgets/accessible/itemviews.cpp | 1222 ++++++++++++++++++++ src/widgets/accessible/itemviews.h | 292 +++++ src/widgets/accessible/qaccessiblemenu.cpp | 377 ++++++ src/widgets/accessible/qaccessiblemenu.h | 131 +++ src/widgets/accessible/qaccessiblewidget.cpp | 4 +- .../accessible/qaccessiblewidgetfactory.cpp | 241 ++++ .../accessible/qaccessiblewidgetfactory_p.h | 53 + src/widgets/accessible/qaccessiblewidgets.cpp | 1019 ++++++++++++++++ src/widgets/accessible/qaccessiblewidgets.h | 314 +++++ src/widgets/accessible/rangecontrols.cpp | 323 ++++++ src/widgets/accessible/rangecontrols.h | 160 +++ src/widgets/accessible/simplewidgets.cpp | 886 ++++++++++++++ src/widgets/accessible/simplewidgets.h | 215 ++++ src/widgets/accessible/widgets.pro | 26 + src/widgets/kernel/qapplication.cpp | 6 + src/widgets/widgets.pro | 3 - 36 files changed, 5890 insertions(+), 5899 deletions(-) delete mode 100644 src/plugins/accessible/accessible.pro delete mode 100644 src/plugins/accessible/widgets/complexwidgets.cpp delete mode 100644 src/plugins/accessible/widgets/complexwidgets.h delete mode 100644 src/plugins/accessible/widgets/itemviews.cpp delete mode 100644 src/plugins/accessible/widgets/itemviews.h delete mode 100644 src/plugins/accessible/widgets/main.cpp delete mode 100644 src/plugins/accessible/widgets/qaccessiblemenu.cpp delete mode 100644 src/plugins/accessible/widgets/qaccessiblemenu.h delete mode 100644 src/plugins/accessible/widgets/qaccessiblewidgets.cpp delete mode 100644 src/plugins/accessible/widgets/qaccessiblewidgets.h delete mode 100644 src/plugins/accessible/widgets/rangecontrols.cpp delete mode 100644 src/plugins/accessible/widgets/rangecontrols.h delete mode 100644 src/plugins/accessible/widgets/simplewidgets.cpp delete mode 100644 src/plugins/accessible/widgets/simplewidgets.h delete mode 100644 src/plugins/accessible/widgets/widgets.json delete mode 100644 src/plugins/accessible/widgets/widgets.pro create mode 100644 src/widgets/accessible/complexwidgets.cpp create mode 100644 src/widgets/accessible/complexwidgets.h create mode 100644 src/widgets/accessible/itemviews.cpp create mode 100644 src/widgets/accessible/itemviews.h create mode 100644 src/widgets/accessible/qaccessiblemenu.cpp create mode 100644 src/widgets/accessible/qaccessiblemenu.h create mode 100644 src/widgets/accessible/qaccessiblewidgetfactory.cpp create mode 100644 src/widgets/accessible/qaccessiblewidgetfactory_p.h create mode 100644 src/widgets/accessible/qaccessiblewidgets.cpp create mode 100644 src/widgets/accessible/qaccessiblewidgets.h create mode 100644 src/widgets/accessible/rangecontrols.cpp create mode 100644 src/widgets/accessible/rangecontrols.h create mode 100644 src/widgets/accessible/simplewidgets.cpp create mode 100644 src/widgets/accessible/simplewidgets.h create mode 100644 src/widgets/accessible/widgets.pro diff --git a/src/plugins/accessible/accessible.pro b/src/plugins/accessible/accessible.pro deleted file mode 100644 index 26c7d3066d..0000000000 --- a/src/plugins/accessible/accessible.pro +++ /dev/null @@ -1,5 +0,0 @@ -TEMPLATE = subdirs - -contains(QT_CONFIG, accessibility) { - SUBDIRS += widgets -} diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp deleted file mode 100644 index b1df6d816a..0000000000 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "complexwidgets.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_ACCESSIBILITY - -QT_BEGIN_NAMESPACE - -QString Q_GUI_EXPORT qt_accStripAmp(const QString &text); - -#ifndef QT_NO_TABBAR -/*! - \class QAccessibleTabBar - \brief The QAccessibleTabBar class implements the QAccessibleInterface for tab bars. - \internal - - \ingroup accessibility -*/ - -class QAccessibleTabButton: public QAccessibleInterface, public QAccessibleActionInterface -{ -public: - QAccessibleTabButton(QTabBar *parent, int index) - : m_parent(parent), m_index(index) - {} - - void *interface_cast(QAccessible::InterfaceType t) { - if (t == QAccessible::ActionInterface) { - return static_cast(this); - } - return 0; - } - - QObject *object() const { return 0; } - QAccessible::Role role() const { return QAccessible::PageTab; } - QAccessible::State state() const { - QAccessibleInterface *parentInterface = parent(); - QAccessible::State state = parentInterface->state(); - return state; - } - QRect rect() const { - if (!isValid()) - return QRect(); - - QPoint tp = m_parent->mapToGlobal(QPoint(0,0)); - QRect rec = m_parent->tabRect(m_index); - rec = QRect(tp.x() + rec.x(), tp.y() + rec.y(), rec.width(), rec.height()); - return rec; - } - - bool isValid() const { return true; }// (!m_parent.isNull()) && m_parent->count() > m_index; } - - QAccessibleInterface *childAt(int, int) const { return 0; } - int childCount() const { return 0; } - int indexOfChild(const QAccessibleInterface *) const { return -1; } - - QString text(QAccessible::Text) const { return qt_accStripAmp(m_parent->tabText(m_index)); } - void setText(QAccessible::Text, const QString &) {} - - QAccessibleInterface *parent() const { - return QAccessible::queryAccessibleInterface(m_parent); - } - QAccessibleInterface *child(int) const { return 0; } - // action interface - QStringList actionNames() const - { - return QStringList(pressAction()); - } - - void doAction(const QString &actionName) - { - if (actionName == pressAction()) - m_parent->setCurrentIndex(m_index); - } - - QStringList keyBindingsForAction(const QString &) const - { - return QStringList(); - } - - int index() const { return m_index; } - -private: - QPointer m_parent; - int m_index; - -}; - -/*! - Constructs a QAccessibleTabBar object for \a w. -*/ -QAccessibleTabBar::QAccessibleTabBar(QWidget *w) -: QAccessibleWidget(w, QAccessible::PageTabList) -{ - Q_ASSERT(tabBar()); -} - -QAccessibleTabBar::~QAccessibleTabBar() -{ - foreach (QAccessible::Id id, m_childInterfaces.values()) - QAccessible::deleteAccessibleInterface(id); -} - -/*! Returns the QTabBar. */ -QTabBar *QAccessibleTabBar::tabBar() const -{ - return qobject_cast(object()); -} - -QAccessibleInterface* QAccessibleTabBar::child(int index) const -{ - if (QAccessible::Id id = m_childInterfaces.value(index)) - return QAccessible::accessibleInterface(id); - - // first the tabs, then 2 buttons - if (index < tabBar()->count()) { - QAccessibleTabButton *button = new QAccessibleTabButton(tabBar(), index); - QAccessible::registerAccessibleInterface(button); - m_childInterfaces.insert(index, QAccessible::uniqueId(button)); - return button; - } else if (index >= tabBar()->count()) { - // left button - if (index - tabBar()->count() == 0) { - return QAccessible::queryAccessibleInterface(tabBar()->d_func()->leftB); - } - // right button - if (index - tabBar()->count() == 1) { - return QAccessible::queryAccessibleInterface(tabBar()->d_func()->rightB); - } - } - return 0; -} - -int QAccessibleTabBar::indexOfChild(const QAccessibleInterface *child) const -{ - if (child->object() && child->object() == tabBar()->d_func()->leftB) - return tabBar()->count(); - if (child->object() && child->object() == tabBar()->d_func()->rightB) - return tabBar()->count() + 1; - if (child->role() == QAccessible::PageTab) { - QAccessibleInterface *parent = child->parent(); - if (parent == this) { - const QAccessibleTabButton *tabButton = static_cast(child); - return tabButton->index(); - } - } - return -1; -} - -int QAccessibleTabBar::childCount() const -{ - // tabs + scroll buttons - return tabBar()->count() + 2; -} - -QString QAccessibleTabBar::text(QAccessible::Text t) const -{ - if (t == QAccessible::Name) { - return qt_accStripAmp(tabBar()->tabText(tabBar()->currentIndex())); - } - return QString(); -} - -#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 -*/ - -/*! - Constructs a QAccessibleComboBox object for \a w. -*/ -QAccessibleComboBox::QAccessibleComboBox(QWidget *w) -: QAccessibleWidget(w, QAccessible::ComboBox) -{ - Q_ASSERT(comboBox()); -} - -/*! - Returns the combobox. -*/ -QComboBox *QAccessibleComboBox::comboBox() const -{ - return qobject_cast(object()); -} - -QAccessibleInterface *QAccessibleComboBox::child(int index) const -{ - if (index == 0) { - QAbstractItemView *view = comboBox()->view(); - //QWidget *parent = view ? view->parentWidget() : 0; - return QAccessible::queryAccessibleInterface(view); - } else if (index == 1 && comboBox()->isEditable()) { - return QAccessible::queryAccessibleInterface(comboBox()->lineEdit()); - } - return 0; -} - -int QAccessibleComboBox::childCount() const -{ - // list and text edit - return comboBox()->isEditable() ? 2 : 1; -} - -QAccessibleInterface *QAccessibleComboBox::childAt(int x, int y) const -{ - if (comboBox()->isEditable() && comboBox()->lineEdit()->rect().contains(x, y)) - return child(1); - return 0; -} - -int QAccessibleComboBox::indexOfChild(const QAccessibleInterface *child) const -{ - if (comboBox()->view() == child->object()) - return 0; - if (comboBox()->isEditable() && comboBox()->lineEdit() == child->object()) - return 1; - return -1; -} - -/*! \reimp */ -QString QAccessibleComboBox::text(QAccessible::Text t) const -{ - QString str; - - switch (t) { - case QAccessible::Name: -#ifndef Q_OS_UNIX // on Linux we use relations for this, name is text (fall through to Value) - str = QAccessibleWidget::text(t); - break; -#endif - case QAccessible::Value: - if (comboBox()->isEditable()) - str = comboBox()->lineEdit()->text(); - else - str = comboBox()->currentText(); - break; -#ifndef QT_NO_SHORTCUT - case QAccessible::Accelerator: - str = QKeySequence(Qt::Key_Down).toString(QKeySequence::NativeText); - break; -#endif - default: - break; - } - if (str.isEmpty()) - str = QAccessibleWidget::text(t); - return str; -} - -QStringList QAccessibleComboBox::actionNames() const -{ - return QStringList(showMenuAction()); -} - -QString QAccessibleComboBox::localizedActionDescription(const QString &actionName) const -{ - if (actionName == showMenuAction()) - return QComboBox::tr("Open the combo box selection popup"); - return QString(); -} - -void QAccessibleComboBox::doAction(const QString &actionName) -{ - if (actionName == showMenuAction()) { - if (comboBox()->view()->isVisible()) { - comboBox()->hidePopup(); - } else { - comboBox()->showPopup(); - } - } -} - -QStringList QAccessibleComboBox::keyBindingsForAction(const QString &/*actionName*/) const -{ - return QStringList(); -} - -#endif // QT_NO_COMBOBOX - -#ifndef QT_NO_SCROLLAREA -// ======================= QAccessibleAbstractScrollArea ======================= -QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Client) -{ - Q_ASSERT(qobject_cast(widget)); -} - -QAccessibleInterface *QAccessibleAbstractScrollArea::child(int index) const -{ - return QAccessible::queryAccessibleInterface(accessibleChildren().at(index)); -} - -int QAccessibleAbstractScrollArea::childCount() const -{ - return accessibleChildren().count(); -} - -int QAccessibleAbstractScrollArea::indexOfChild(const QAccessibleInterface *child) const -{ - if (!child || !child->object()) - return -1; - return accessibleChildren().indexOf(qobject_cast(child->object())); -} - -bool QAccessibleAbstractScrollArea::isValid() const -{ - return (QAccessibleWidget::isValid() && abstractScrollArea() && abstractScrollArea()->viewport()); -} - -QAccessibleInterface *QAccessibleAbstractScrollArea::childAt(int x, int y) const -{ - if (!abstractScrollArea()->isVisible()) - return 0; - - for (int i = 0; i < childCount(); ++i) { - QPoint wpos = accessibleChildren().at(i)->mapToGlobal(QPoint(0, 0)); - QRect rect = QRect(wpos, accessibleChildren().at(i)->size()); - if (rect.contains(x, y)) - return child(i); - } - return 0; -} - -QAbstractScrollArea *QAccessibleAbstractScrollArea::abstractScrollArea() const -{ - return static_cast(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(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 deleted file mode 100644 index 00186282f3..0000000000 --- a/src/plugins/accessible/widgets/complexwidgets.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef COMPLEXWIDGETS_H -#define COMPLEXWIDGETS_H - -#include -#include -#include - -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 QAccessibleWidget -{ -public: - explicit QAccessibleAbstractScrollArea(QWidget *widget); - - enum AbstractScrollAreaElement { - Self = 0, - Viewport, - HorizontalContainer, - VerticalContainer, - CornerWidget, - Undefined - }; - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - -//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_TABBAR -class QAccessibleTabBar : public QAccessibleWidget -{ -public: - explicit QAccessibleTabBar(QWidget *w); - ~QAccessibleTabBar(); - - int childCount() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - -protected: - QTabBar *tabBar() const; - mutable QHash m_childInterfaces; -}; -#endif // QT_NO_TABBAR - -#ifndef QT_NO_COMBOBOX -class QAccessibleComboBox : public QAccessibleWidget -{ -public: - explicit QAccessibleComboBox(QWidget *w); - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - // QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - QString localizedActionDescription(const QString &actionName) const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - -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/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp deleted file mode 100644 index 7d3668ee5a..0000000000 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ /dev/null @@ -1,1222 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "itemviews.h" - -#include -#include -#include -#include -#include - -#ifndef QT_NO_ACCESSIBILITY - -QT_BEGIN_NAMESPACE - -QString Q_GUI_EXPORT qt_accStripAmp(const QString &text); - -#ifndef QT_NO_ITEMVIEWS -/* -Implementation of the IAccessible2 table2 interface. Much simpler than -the other table interfaces since there is only the main table and cells: - -TABLE/LIST/TREE - |- HEADER CELL - |- CELL - |- CELL - ... -*/ - - -QAbstractItemView *QAccessibleTable::view() const -{ - return qobject_cast(object()); -} - -int QAccessibleTable::logicalIndex(const QModelIndex &index) const -{ - if (!view()->model() || !index.isValid()) - return -1; - int vHeader = verticalHeader() ? 1 : 0; - int hHeader = horizontalHeader() ? 1 : 0; - return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader); -} - -QAccessibleTable::QAccessibleTable(QWidget *w) - : QAccessibleObject(w) -{ - Q_ASSERT(view()); - - if (qobject_cast(view())) { - m_role = QAccessible::Table; - } else if (qobject_cast(view())) { - m_role = QAccessible::Tree; - } else if (qobject_cast(view())) { - m_role = QAccessible::List; - } else { - // is this our best guess? - m_role = QAccessible::Table; - } -} - -bool QAccessibleTable::isValid() const -{ - return (view() && !qobject_cast(view())->d_func()->data.in_destructor); -} - -QAccessibleTable::~QAccessibleTable() -{ - Q_FOREACH (QAccessible::Id id, childToId.values()) - QAccessible::deleteAccessibleInterface(id); -} - -QHeaderView *QAccessibleTable::horizontalHeader() const -{ - QHeaderView *header = 0; - if (false) { -#ifndef QT_NO_TABLEVIEW - } else if (const QTableView *tv = qobject_cast(view())) { - header = tv->horizontalHeader(); -#endif -#ifndef QT_NO_TREEVIEW - } else if (const QTreeView *tv = qobject_cast(view())) { - header = tv->header(); -#endif - } - return header; -} - -QHeaderView *QAccessibleTable::verticalHeader() const -{ - QHeaderView *header = 0; - if (false) { -#ifndef QT_NO_TABLEVIEW - } else if (const QTableView *tv = qobject_cast(view())) { - header = tv->verticalHeader(); -#endif - } - return header; -} - -QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const -{ - if (!view()->model()) - return 0; - Q_ASSERT(role() != QAccessible::Tree); - QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); - if (!index.isValid()) { - qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view(); - return 0; - } - return child(logicalIndex(index)); -} - -QAccessibleInterface *QAccessibleTable::caption() const -{ - return 0; -} - -QString QAccessibleTable::columnDescription(int column) const -{ - if (!view()->model()) - return QString(); - return view()->model()->headerData(column, Qt::Horizontal).toString(); -} - -int QAccessibleTable::columnCount() const -{ - if (!view()->model()) - return 0; - return view()->model()->columnCount(); -} - -int QAccessibleTable::rowCount() const -{ - if (!view()->model()) - return 0; - return view()->model()->rowCount(); -} - -int QAccessibleTable::selectedCellCount() const -{ - if (!view()->selectionModel()) - return 0; - return view()->selectionModel()->selectedIndexes().count(); -} - -int QAccessibleTable::selectedColumnCount() const -{ - if (!view()->selectionModel()) - return 0; - return view()->selectionModel()->selectedColumns().count(); -} - -int QAccessibleTable::selectedRowCount() const -{ - if (!view()->selectionModel()) - return 0; - return view()->selectionModel()->selectedRows().count(); -} - -QString QAccessibleTable::rowDescription(int row) const -{ - if (!view()->model()) - return QString(); - return view()->model()->headerData(row, Qt::Vertical).toString(); -} - -QList QAccessibleTable::selectedCells() const -{ - QList cells; - if (!view()->selectionModel()) - return cells; - Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes()) - cells.append(child(logicalIndex(index))); - return cells; -} - -QList QAccessibleTable::selectedColumns() const -{ - if (!view()->selectionModel()) - return QList(); - QList columns; - Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) { - columns.append(index.column()); - } - return columns; -} - -QList QAccessibleTable::selectedRows() const -{ - if (!view()->selectionModel()) - return QList(); - QList rows; - Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) { - rows.append(index.row()); - } - return rows; -} - -QAccessibleInterface *QAccessibleTable::summary() const -{ - return 0; -} - -bool QAccessibleTable::isColumnSelected(int column) const -{ - if (!view()->selectionModel()) - return false; - return view()->selectionModel()->isColumnSelected(column, QModelIndex()); -} - -bool QAccessibleTable::isRowSelected(int row) const -{ - if (!view()->selectionModel()) - return false; - return view()->selectionModel()->isRowSelected(row, QModelIndex()); -} - -bool QAccessibleTable::selectRow(int row) -{ - if (!view()->model() || !view()->selectionModel()) - return false; - QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); - - if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) - return false; - - switch (view()->selectionMode()) { - case QAbstractItemView::NoSelection: - return false; - case QAbstractItemView::SingleSelection: - if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 ) - return false; - view()->clearSelection(); - break; - case QAbstractItemView::ContiguousSelection: - if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) - && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) - view()->clearSelection(); - break; - default: - break; - } - - view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); - return true; -} - -bool QAccessibleTable::selectColumn(int column) -{ - if (!view()->model() || !view()->selectionModel()) - return false; - QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); - - if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectRows) - return false; - - switch (view()->selectionMode()) { - case QAbstractItemView::NoSelection: - return false; - case QAbstractItemView::SingleSelection: - if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) - return false; - case QAbstractItemView::ContiguousSelection: - if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) - && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) - view()->clearSelection(); - break; - default: - break; - } - - view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Columns); - return true; -} - -bool QAccessibleTable::unselectRow(int row) -{ - if (!view()->model() || !view()->selectionModel()) - return false; - - QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); - if (!index.isValid()) - return false; - - QItemSelection selection(index, index); - - switch (view()->selectionMode()) { - case QAbstractItemView::SingleSelection: - //In SingleSelection and ContiguousSelection once an item - //is selected, there's no way for the user to unselect all items - if (selectedRowCount() == 1) - return false; - break; - case QAbstractItemView::ContiguousSelection: - if (selectedRowCount() == 1) - return false; - - if ((!row || view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) - && view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { - //If there are rows selected both up the current row and down the current rown, - //the ones which are down the current row will be deselected - selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex())); - } - default: - break; - } - - view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Rows); - return true; -} - -bool QAccessibleTable::unselectColumn(int column) -{ - if (!view()->model() || !view()->selectionModel()) - return false; - - QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); - if (!index.isValid()) - return false; - - QItemSelection selection(index, index); - - switch (view()->selectionMode()) { - case QAbstractItemView::SingleSelection: - //In SingleSelection and ContiguousSelection once an item - //is selected, there's no way for the user to unselect all items - if (selectedColumnCount() == 1) - return false; - break; - case QAbstractItemView::ContiguousSelection: - if (selectedColumnCount() == 1) - return false; - - if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) - && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { - //If there are columns selected both at the left of the current row and at the right - //of the current rown, the ones which are at the right will be deselected - selection = QItemSelection(index, view()->model()->index(0, columnCount() - 1, view()->rootIndex())); - } - default: - break; - } - - view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Columns); - return true; -} - -QAccessible::Role QAccessibleTable::role() const -{ - return m_role; -} - -QAccessible::State QAccessibleTable::state() const -{ - return QAccessible::State(); -} - -QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const -{ - QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); - QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); - // FIXME: if indexPosition < 0 in one coordinate, return header - - QModelIndex index = view()->indexAt(indexPosition); - if (index.isValid()) { - return child(logicalIndex(index)); - } - return 0; -} - -int QAccessibleTable::childCount() const -{ - if (!view()->model()) - return 0; - int vHeader = verticalHeader() ? 1 : 0; - int hHeader = horizontalHeader() ? 1 : 0; - return (view()->model()->rowCount()+hHeader) * (view()->model()->columnCount()+vHeader); -} - -int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const -{ - if (!view()->model()) - return -1; - QAccessibleInterface *parent = iface->parent(); - if (parent->object() != view()) - return -1; - - Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class - if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { - const QAccessibleTableCell* cell = static_cast(iface); - return logicalIndex(cell->m_index); - } else if (iface->role() == QAccessible::ColumnHeader){ - const QAccessibleTableHeaderCell* cell = static_cast(iface); - return cell->index + (verticalHeader() ? 1 : 0); - } else if (iface->role() == QAccessible::RowHeader){ - const QAccessibleTableHeaderCell* cell = static_cast(iface); - return (cell->index + 1) * (view()->model()->columnCount() + 1); - } else if (iface->role() == QAccessible::Pane) { - return 0; // corner button - } else { - qWarning() << "WARNING QAccessibleTable::indexOfChild Fix my children..." - << iface->role() << iface->text(QAccessible::Name); - } - // FIXME: we are in denial of our children. this should stop. - return -1; -} - -QString QAccessibleTable::text(QAccessible::Text t) const -{ - if (t == QAccessible::Description) - return view()->accessibleDescription(); - return view()->accessibleName(); -} - -QRect QAccessibleTable::rect() const -{ - if (!view()->isVisible()) - return QRect(); - QPoint pos = view()->mapToGlobal(QPoint(0, 0)); - return QRect(pos.x(), pos.y(), view()->width(), view()->height()); -} - -QAccessibleInterface *QAccessibleTable::parent() const -{ - if (view() && view()->parent()) { - if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) { - return QAccessible::queryAccessibleInterface(view()->parent()->parent()); - } - return QAccessible::queryAccessibleInterface(view()->parent()); - } - return 0; -} - -QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const -{ - if (!view()->model()) - return 0; - - if (childToId.contains(logicalIndex)) { - QAccessible::Id id = childToId.value(logicalIndex); - return QAccessible::accessibleInterface(id); - } - - int vHeader = verticalHeader() ? 1 : 0; - int hHeader = horizontalHeader() ? 1 : 0; - - int columns = view()->model()->columnCount() + vHeader; - - int row = logicalIndex / columns; - int column = logicalIndex % columns; - - QAccessibleInterface *iface = 0; - - if (vHeader) { - if (column == 0) { - if (hHeader && row == 0) { - iface = new QAccessibleTableCornerButton(view()); - } else { - iface = new QAccessibleTableHeaderCell(view(), row - hHeader, Qt::Vertical); - } - } - --column; - } - if (!iface && hHeader) { - if (row == 0) { - iface = new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal); - } - --row; - } - - if (!iface) { - QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); - if (!index.isValid()) { - qWarning() << "QAccessibleTable::child: Invalid index at: " << row << column; - return 0; - } - iface = new QAccessibleTableCell(view(), index, cellRole()); - } - - QAccessible::registerAccessibleInterface(iface); - childToId.insert(logicalIndex, QAccessible::uniqueId(iface)); - return iface; -} - -void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::TableInterface) - return static_cast(this); - return 0; -} - -void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event) -{ - // if there is no cache yet, we don't update anything - if (childToId.isEmpty()) - return; - - switch (event->modelChangeType()) { - case QAccessibleTableModelChangeEvent::ModelReset: - Q_FOREACH (QAccessible::Id id, childToId.values()) - QAccessible::deleteAccessibleInterface(id); - childToId.clear(); - break; - - // rows are inserted: move every row after that - case QAccessibleTableModelChangeEvent::RowsInserted: - case QAccessibleTableModelChangeEvent::ColumnsInserted: { - int newRows = event->lastRow() - event->firstRow() + 1; - int newColumns = event->lastColumn() - event->firstColumn() + 1; - - ChildCache newCache; - ChildCache::ConstIterator iter = childToId.constBegin(); - - while (iter != childToId.constEnd()) { - QAccessible::Id id = iter.value(); - QAccessibleInterface *iface = QAccessible::accessibleInterface(id); - Q_ASSERT(iface); - if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { - Q_ASSERT(iface->tableCellInterface()); - QAccessibleTableCell *cell = static_cast(iface->tableCellInterface()); - if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted - && cell->m_index.row() >= event->firstRow()) { - int newRow = cell->m_index.row() + newRows; - cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column()); - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted - && cell->m_index.column() >= event->firstColumn()) { - int newColumn = cell->m_index.column() + newColumns; - cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn); - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted - && iface->role() == QAccessible::RowHeader) { - QAccessibleTableHeaderCell *cell = static_cast(iface); - if (cell->index >= event->firstRow()) { - cell->index += newRows; - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted - && iface->role() == QAccessible::ColumnHeader) { - QAccessibleTableHeaderCell *cell = static_cast(iface); - if (cell->index >= event->firstColumn()) { - cell->index += newColumns; - } - } - if (indexOfChild(iface) >= 0) { - newCache.insert(indexOfChild(iface), id); - } else { - // ### This should really not happen, - // but it might if the view has a root index set. - // This needs to be fixed. - QAccessible::deleteAccessibleInterface(id); - } - ++iter; - } - childToId = newCache; - break; - } - - case QAccessibleTableModelChangeEvent::ColumnsRemoved: - case QAccessibleTableModelChangeEvent::RowsRemoved: { - int deletedColumns = event->lastColumn() - event->firstColumn() + 1; - int deletedRows = event->lastRow() - event->firstRow() + 1; - ChildCache newCache; - ChildCache::ConstIterator iter = childToId.constBegin(); - while (iter != childToId.constEnd()) { - QAccessible::Id id = iter.value(); - QAccessibleInterface *iface = QAccessible::accessibleInterface(id); - Q_ASSERT(iface); - if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { - Q_ASSERT(iface->tableCellInterface()); - QAccessibleTableCell *cell = static_cast(iface->tableCellInterface()); - if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved) { - if (cell->m_index.row() < event->firstRow()) { - newCache.insert(indexOfChild(cell), id); - } else if (cell->m_index.row() > event->lastRow()) { - int newRow = cell->m_index.row() - deletedRows; - cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column()); - newCache.insert(indexOfChild(cell), id); - } else { - QAccessible::deleteAccessibleInterface(id); - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved) { - if (cell->m_index.column() < event->firstColumn()) { - newCache.insert(indexOfChild(cell), id); - } else if (cell->m_index.column() > event->lastColumn()) { - int newColumn = cell->m_index.column() - deletedColumns; - cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn); - newCache.insert(indexOfChild(cell), id); - } else { - QAccessible::deleteAccessibleInterface(id); - } - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved - && iface->role() == QAccessible::RowHeader) { - QAccessibleTableHeaderCell *cell = static_cast(iface); - if (cell->index < event->firstRow()) { - newCache.insert(indexOfChild(cell), id); - } else if (cell->index > event->lastRow()) { - cell->index -= deletedRows; - newCache.insert(indexOfChild(cell), id); - } else { - QAccessible::deleteAccessibleInterface(id); - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved - && iface->role() == QAccessible::ColumnHeader) { - QAccessibleTableHeaderCell *cell = static_cast(iface); - if (cell->index < event->firstColumn()) { - newCache.insert(indexOfChild(cell), id); - } else if (cell->index > event->lastColumn()) { - cell->index -= deletedColumns; - newCache.insert(indexOfChild(cell), id); - } else { - QAccessible::deleteAccessibleInterface(id); - } - } - ++iter; - } - childToId = newCache; - break; - } - - case QAccessibleTableModelChangeEvent::DataChanged: - // nothing to do in this case - break; - } -} - -// TREE VIEW - -QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const -{ - if (!isValid() || !view()->model()) - return QModelIndex(); - - const QTreeView *treeView = qobject_cast(view()); - if ((row < 0) || (column < 0) || (treeView->d_func()->viewItems.count() <= row)) { - qWarning() << "QAccessibleTree::indexFromLogical: invalid index: " << row << column << " for " << treeView; - return QModelIndex(); - } - QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index; - - if (modelIndex.isValid() && column > 0) { - modelIndex = view()->model()->index(modelIndex.row(), column, modelIndex.parent()); - } - return modelIndex; -} - -QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const -{ - if (!view()->model()) - return 0; - QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); - QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); - - QModelIndex index = view()->indexAt(indexPosition); - if (!index.isValid()) - return 0; - - const QTreeView *treeView = qobject_cast(view()); - int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0); - int column = index.column(); - - int i = row * view()->model()->columnCount() + column; - return child(i); -} - -int QAccessibleTree::childCount() const -{ - const QTreeView *treeView = qobject_cast(view()); - Q_ASSERT(treeView); - if (!view()->model()) - return 0; - - int hHeader = horizontalHeader() ? 1 : 0; - return (treeView->d_func()->viewItems.count() + hHeader)* view()->model()->columnCount(); -} - - -QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const -{ - if (logicalIndex < 0 || !view()->model() || !view()->model()->columnCount()) - return 0; - - QAccessibleInterface *iface = 0; - int index = logicalIndex; - - if (horizontalHeader()) { - if (index < view()->model()->columnCount()) { - iface = new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal); - } else { - index -= view()->model()->columnCount(); - } - } - - if (!iface) { - int row = index / view()->model()->columnCount(); - int column = index % view()->model()->columnCount(); - QModelIndex modelIndex = indexFromLogical(row, column); - if (!modelIndex.isValid()) - return 0; - iface = new QAccessibleTableCell(view(), modelIndex, cellRole()); - } - QAccessible::registerAccessibleInterface(iface); - // ### FIXME: get interfaces from the cache instead of re-creating them - return iface; -} - -int QAccessibleTree::rowCount() const -{ - const QTreeView *treeView = qobject_cast(view()); - Q_ASSERT(treeView); - return treeView->d_func()->viewItems.count(); -} - -int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const -{ - if (!view()->model()) - return -1; - QAccessibleInterface *parent = iface->parent(); - if (parent->object() != view()) - return -1; - - if (iface->role() == QAccessible::TreeItem) { - const QAccessibleTableCell* cell = static_cast(iface); - const QTreeView *treeView = qobject_cast(view()); - Q_ASSERT(treeView); - int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0); - int column = cell->m_index.column(); - - int index = row * view()->model()->columnCount() + column; - return index; - } else if (iface->role() == QAccessible::ColumnHeader){ - const QAccessibleTableHeaderCell* cell = static_cast(iface); - return cell->index; - } else { - qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child" - << iface->role() << iface->text(QAccessible::Name); - } - // FIXME: add scrollbars and don't just ignore them - return -1; -} - -QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const -{ - QModelIndex index = indexFromLogical(row, column); - if (!index.isValid()) { - qWarning() << "Requested invalid tree cell: " << row << column; - return 0; - } - const QTreeView *treeView = qobject_cast(view()); - Q_ASSERT(treeView); - int logicalIndex = treeView->d_func()->accessibleTable2Index(index); - - return child(logicalIndex); // FIXME ### new QAccessibleTableCell(view(), index, cellRole()); -} - -QString QAccessibleTree::rowDescription(int) const -{ - return QString(); // no headers for rows in trees -} - -bool QAccessibleTree::isRowSelected(int row) const -{ - if (!view()->selectionModel()) - return false; - QModelIndex index = indexFromLogical(row); - return view()->selectionModel()->isRowSelected(index.row(), index.parent()); -} - -bool QAccessibleTree::selectRow(int row) -{ - if (!view()->selectionModel()) - return false; - QModelIndex index = indexFromLogical(row); - - if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) - return false; - - switch (view()->selectionMode()) { - case QAbstractItemView::NoSelection: - return false; - case QAbstractItemView::SingleSelection: - if ((view()->selectionBehavior() != QAbstractItemView::SelectRows) && (columnCount() > 1)) - return false; - view()->clearSelection(); - break; - case QAbstractItemView::ContiguousSelection: - if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) - && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) - view()->clearSelection(); - break; - default: - break; - } - - view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); - return true; -} - -// TABLE CELL - -QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_) - : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_) -{ - if (!index_.isValid()) - qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_; -} - -void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::TableCellInterface) - return static_cast(this); - if (t == QAccessible::ActionInterface) - return static_cast(this); - return 0; -} - -int QAccessibleTableCell::columnExtent() const { return 1; } -int QAccessibleTableCell::rowExtent() const { return 1; } - -QList QAccessibleTableCell::rowHeaderCells() const -{ - QList headerCell; - if (verticalHeader()) { - // FIXME - headerCell.append(new QAccessibleTableHeaderCell(view, m_index.row(), Qt::Vertical)); - } - return headerCell; -} - -QList QAccessibleTableCell::columnHeaderCells() const -{ - QList headerCell; - if (horizontalHeader()) { - // FIXME - headerCell.append(new QAccessibleTableHeaderCell(view, m_index.column(), Qt::Horizontal)); - } - return headerCell; -} - -QHeaderView *QAccessibleTableCell::horizontalHeader() const -{ - QHeaderView *header = 0; - - if (false) { -#ifndef QT_NO_TABLEVIEW - } else if (const QTableView *tv = qobject_cast(view)) { - header = tv->horizontalHeader(); -#endif -#ifndef QT_NO_TREEVIEW - } else if (const QTreeView *tv = qobject_cast(view)) { - header = tv->header(); -#endif - } - - return header; -} - -QHeaderView *QAccessibleTableCell::verticalHeader() const -{ - QHeaderView *header = 0; -#ifndef QT_NO_TABLEVIEW - if (const QTableView *tv = qobject_cast(view)) - header = tv->verticalHeader(); -#endif - return header; -} - -int QAccessibleTableCell::columnIndex() const -{ - return m_index.column(); -} - -int QAccessibleTableCell::rowIndex() const -{ - if (role() == QAccessible::TreeItem) { - const QTreeView *treeView = qobject_cast(view); - Q_ASSERT(treeView); - int row = treeView->d_func()->viewIndex(m_index); - return row; - } - return m_index.row(); -} - -bool QAccessibleTableCell::isSelected() const -{ - return view->selectionModel()->isSelected(m_index); -} - -QStringList QAccessibleTableCell::actionNames() const -{ - QStringList names; - names << toggleAction(); - return names; -} - -void QAccessibleTableCell::doAction(const QString& actionName) -{ - if (actionName == toggleAction()) { - if (isSelected()) - unselectCell(); - else - selectCell(); - } -} - -QStringList QAccessibleTableCell::keyBindingsForAction(const QString &) const -{ - return QStringList(); -} - - -void QAccessibleTableCell::selectCell() -{ - QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); - if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection)) - return; - Q_ASSERT(table()); - QAccessibleTableInterface *cellTable = table()->tableInterface(); - - switch (view->selectionBehavior()) { - case QAbstractItemView::SelectItems: - break; - case QAbstractItemView::SelectColumns: - if (cellTable) - cellTable->selectColumn(m_index.column()); - return; - case QAbstractItemView::SelectRows: - if (cellTable) - cellTable->selectRow(m_index.row()); - return; - } - - if (selectionMode == QAbstractItemView::SingleSelection) { - view->clearSelection(); - } - - view->selectionModel()->select(m_index, QItemSelectionModel::Select); -} - -void QAccessibleTableCell::unselectCell() -{ - - QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); - if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection)) - return; - - QAccessibleTableInterface *cellTable = table()->tableInterface(); - - switch (view->selectionBehavior()) { - case QAbstractItemView::SelectItems: - break; - case QAbstractItemView::SelectColumns: - if (cellTable) - cellTable->unselectColumn(m_index.column()); - return; - case QAbstractItemView::SelectRows: - if (cellTable) - cellTable->unselectRow(m_index.row()); - return; - } - - //If the mode is not MultiSelection or ExtendedSelection and only - //one cell is selected it cannot be unselected by the user - if ((selectionMode != QAbstractItemView::MultiSelection) - && (selectionMode != QAbstractItemView::ExtendedSelection) - && (view->selectionModel()->selectedIndexes().count() <= 1)) - return; - - view->selectionModel()->select(m_index, QItemSelectionModel::Deselect); -} - -QAccessibleInterface *QAccessibleTableCell::table() const -{ - return QAccessible::queryAccessibleInterface(view); -} - -QAccessible::Role QAccessibleTableCell::role() const -{ - return m_role; -} - -QAccessible::State QAccessibleTableCell::state() const -{ - QAccessible::State st; - QRect globalRect = view->rect(); - globalRect.translate(view->mapToGlobal(QPoint(0,0))); - if (!globalRect.intersects(rect())) - st.invisible = true; - - if (view->selectionModel()->isSelected(m_index)) - st.selected = true; - if (view->selectionModel()->currentIndex() == m_index) - st.focused = true; - if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked) - st.checked = true; - - Qt::ItemFlags flags = m_index.flags(); - if (flags & Qt::ItemIsSelectable) { - st.selectable = true; - st.focusable = true; - if (view->selectionMode() == QAbstractItemView::MultiSelection) - st.multiSelectable = true; - if (view->selectionMode() == QAbstractItemView::ExtendedSelection) - st.extSelectable = true; - } - if (m_role == QAccessible::TreeItem) { - const QTreeView *treeView = qobject_cast(view); - if (treeView->model()->hasChildren(m_index)) - st.expandable = true; - if (treeView->isExpanded(m_index)) - st.expanded = true; - } - return st; -} - - -QRect QAccessibleTableCell::rect() const -{ - QRect r; - r = view->visualRect(m_index); - - if (!r.isNull()) { - r.translate(view->viewport()->mapTo(view, QPoint(0,0))); - r.translate(view->mapToGlobal(QPoint(0, 0))); - } - return r; -} - -QString QAccessibleTableCell::text(QAccessible::Text t) const -{ - QAbstractItemModel *model = view->model(); - QString value; - switch (t) { - case QAccessible::Name: - value = model->data(m_index, Qt::AccessibleTextRole).toString(); - if (value.isEmpty()) - value = model->data(m_index, Qt::DisplayRole).toString(); - break; - case QAccessible::Description: - value = model->data(m_index, Qt::AccessibleDescriptionRole).toString(); - break; - default: - break; - } - return value; -} - -void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text) -{ - if (!(m_index.flags() & Qt::ItemIsEditable)) - return; - view->model()->setData(m_index, text); -} - -bool QAccessibleTableCell::isValid() const -{ - return view && view->model() && m_index.isValid(); -} - -QAccessibleInterface *QAccessibleTableCell::parent() const -{ - return QAccessible::queryAccessibleInterface(view); -} - -QAccessibleInterface *QAccessibleTableCell::child(int) const -{ - return 0; -} - -QAccessibleTableHeaderCell::QAccessibleTableHeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_) - : view(view_), index(index_), orientation(orientation_) -{ - Q_ASSERT(index_ >= 0); -} - -QAccessible::Role QAccessibleTableHeaderCell::role() const -{ - if (orientation == Qt::Horizontal) - return QAccessible::ColumnHeader; - return QAccessible::RowHeader; -} - -QAccessible::State QAccessibleTableHeaderCell::state() const -{ - QAccessible::State s; - if (QHeaderView *h = headerView()) { - s.invisible = !h->testAttribute(Qt::WA_WState_Visible); - s.disabled = !h->isEnabled(); - } - return s; -} - -QRect QAccessibleTableHeaderCell::rect() const -{ - QHeaderView *header = 0; - if (false) { -#ifndef QT_NO_TABLEVIEW - } else if (const QTableView *tv = qobject_cast(view)) { - if (orientation == Qt::Horizontal) { - header = tv->horizontalHeader(); - } else { - header = tv->verticalHeader(); - } -#endif -#ifndef QT_NO_TREEVIEW - } else if (const QTreeView *tv = qobject_cast(view)) { - header = tv->header(); -#endif - } - if (!header) - return QRect(); - QPoint zero = header->mapToGlobal(QPoint(0, 0)); - int sectionSize = header->sectionSize(index); - int sectionPos = header->sectionPosition(index); - return orientation == Qt::Horizontal - ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height()) - : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize); -} - -QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const -{ - QAbstractItemModel *model = view->model(); - QString value; - switch (t) { - case QAccessible::Name: - value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString(); - if (value.isEmpty()) - value = model->headerData(index, orientation, Qt::DisplayRole).toString(); - break; - case QAccessible::Description: - value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString(); - break; - default: - break; - } - return value; -} - -void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &) -{ - return; -} - -bool QAccessibleTableHeaderCell::isValid() const -{ - return view && view->model() && (index >= 0) - && ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount())); -} - -QAccessibleInterface *QAccessibleTableHeaderCell::parent() const -{ - return QAccessible::queryAccessibleInterface(view); -} - -QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const -{ - return 0; -} - -QHeaderView *QAccessibleTableHeaderCell::headerView() const -{ - QHeaderView *header = 0; - if (false) { -#ifndef QT_NO_TABLEVIEW - } else if (const QTableView *tv = qobject_cast(view)) { - if (orientation == Qt::Horizontal) { - header = tv->horizontalHeader(); - } else { - header = tv->verticalHeader(); - } -#endif -#ifndef QT_NO_TREEVIEW - } else if (const QTreeView *tv = qobject_cast(view)) { - header = tv->header(); -#endif - } - return header; -} - -#endif // QT_NO_ITEMVIEWS - -QT_END_NAMESPACE - -#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h deleted file mode 100644 index 45a07c5972..0000000000 --- a/src/plugins/accessible/widgets/itemviews.h +++ /dev/null @@ -1,292 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ACCESSIBLE_ITEMVIEWS_H -#define ACCESSIBLE_ITEMVIEWS_H - -#include "QtCore/qpointer.h" -#include -#include -#include -#include - - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -#ifndef QT_NO_ITEMVIEWS - -class QAccessibleTableCell; -class QAccessibleTableHeaderCell; - -class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObject -{ -public: - explicit QAccessibleTable(QWidget *w); - bool isValid() const Q_DECL_OVERRIDE; - - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // table interface - virtual QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; - virtual QAccessibleInterface *caption() const Q_DECL_OVERRIDE; - virtual QAccessibleInterface *summary() const Q_DECL_OVERRIDE; - virtual QString columnDescription(int column) const Q_DECL_OVERRIDE; - virtual QString rowDescription(int row) const Q_DECL_OVERRIDE; - virtual int columnCount() const Q_DECL_OVERRIDE; - virtual int rowCount() const Q_DECL_OVERRIDE; - - // selection - virtual int selectedCellCount() const Q_DECL_OVERRIDE; - virtual int selectedColumnCount() const Q_DECL_OVERRIDE; - virtual int selectedRowCount() const Q_DECL_OVERRIDE; - virtual QList selectedCells() const Q_DECL_OVERRIDE; - virtual QList selectedColumns() const Q_DECL_OVERRIDE; - virtual QList selectedRows() const Q_DECL_OVERRIDE; - virtual bool isColumnSelected(int column) const Q_DECL_OVERRIDE; - virtual bool isRowSelected(int row) const Q_DECL_OVERRIDE; - virtual bool selectRow(int row) Q_DECL_OVERRIDE; - virtual bool selectColumn(int column) Q_DECL_OVERRIDE; - virtual bool unselectRow(int row) Q_DECL_OVERRIDE; - virtual bool unselectColumn(int column) Q_DECL_OVERRIDE; - - QAbstractItemView *view() const; - - void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE; - -protected: - inline QAccessible::Role cellRole() const { - switch (m_role) { - case QAccessible::List: - return QAccessible::ListItem; - case QAccessible::Table: - return QAccessible::Cell; - case QAccessible::Tree: - return QAccessible::TreeItem; - default: - Q_ASSERT(0); - } - return QAccessible::NoRole; - } - - QHeaderView *horizontalHeader() const; - QHeaderView *verticalHeader() const; - - // maybe vector - typedef QHash ChildCache; - mutable ChildCache childToId; - - virtual ~QAccessibleTable(); - -private: - // the child index for a model index - inline int logicalIndex(const QModelIndex &index) const; - QAccessible::Role m_role; -}; - -class QAccessibleTree :public QAccessibleTable -{ -public: - explicit QAccessibleTree(QWidget *w) - : QAccessibleTable(w) - {} - - - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; - - int rowCount() const Q_DECL_OVERRIDE; - - // table interface - QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; - QString rowDescription(int row) const Q_DECL_OVERRIDE; - bool isRowSelected(int row) const Q_DECL_OVERRIDE; - bool selectRow(int row) Q_DECL_OVERRIDE; - -private: - QModelIndex indexFromLogical(int row, int column = 0) const; - - inline int logicalIndex(const QModelIndex &index) const; -}; - -class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface -{ -public: - QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - QObject *object() const Q_DECL_OVERRIDE { return 0; } - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } - int childCount() const Q_DECL_OVERRIDE { return 0; } - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int) const Q_DECL_OVERRIDE; - - // cell interface - virtual int columnExtent() const Q_DECL_OVERRIDE; - virtual QList columnHeaderCells() const Q_DECL_OVERRIDE; - virtual int columnIndex() const Q_DECL_OVERRIDE; - virtual int rowExtent() const Q_DECL_OVERRIDE; - virtual QList rowHeaderCells() const Q_DECL_OVERRIDE; - virtual int rowIndex() const Q_DECL_OVERRIDE; - virtual bool isSelected() const Q_DECL_OVERRIDE; - virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE; - - //action interface - virtual QStringList actionNames() const Q_DECL_OVERRIDE; - virtual void doAction(const QString &actionName) Q_DECL_OVERRIDE; - virtual QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - -private: - QHeaderView *verticalHeader() const; - QHeaderView *horizontalHeader() const; - QPointer view; - QModelIndex m_index; - QAccessible::Role m_role; - - void selectCell(); - void unselectCell(); - -friend class QAccessibleTable; -friend class QAccessibleTree; -}; - - -class QAccessibleTableHeaderCell: public QAccessibleInterface -{ -public: - // For header cells, pass the header view in addition - QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); - - QObject *object() const Q_DECL_OVERRIDE { return 0; } - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } - int childCount() const Q_DECL_OVERRIDE { return 0; } - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - -private: - QHeaderView *headerView() const; - - QPointer view; - int index; - Qt::Orientation orientation; - -friend class QAccessibleTable; -friend class QAccessibleTree; -}; - -// This is the corner button on the top left of a table. -// It can be used to select all cells or it is not active at all. -// For now it is ignored. -class QAccessibleTableCornerButton: public QAccessibleInterface -{ -public: - QAccessibleTableCornerButton(QAbstractItemView *view_) - :view(view_) - {} - - QObject *object() const Q_DECL_OVERRIDE { return 0; } - QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::Pane; } - QAccessible::State state() const Q_DECL_OVERRIDE { return QAccessible::State(); } - QRect rect() const Q_DECL_OVERRIDE { return QRect(); } - bool isValid() const Q_DECL_OVERRIDE { return true; } - - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } - int childCount() const Q_DECL_OVERRIDE { return 0; } - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } - - QString text(QAccessible::Text) const Q_DECL_OVERRIDE { return QString(); } - void setText(QAccessible::Text, const QString &) Q_DECL_OVERRIDE {} - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE { - return QAccessible::queryAccessibleInterface(view); - } - QAccessibleInterface *child(int) const Q_DECL_OVERRIDE { - return 0; - } - -private: - QPointer view; -}; - - -#endif - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // ACCESSIBLE_ITEMVIEWS_H diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp deleted file mode 100644 index 717c15edd1..0000000000 --- a/src/plugins/accessible/widgets/main.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qaccessiblewidgets.h" -#include "qaccessiblemenu.h" -#include "simplewidgets.h" -#include "rangecontrols.h" -#include "complexwidgets.h" -#include "itemviews.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_ACCESSIBILITY - -QT_BEGIN_NAMESPACE - - -class AccessibleFactory : public QAccessiblePlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QAccessibleFactoryInterface" FILE "widgets.json") - -public: - AccessibleFactory(); - - QAccessibleInterface *create(const QString &classname, QObject *object); -}; - -AccessibleFactory::AccessibleFactory() -{ -} - -QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObject *object) -{ - QAccessibleInterface *iface = 0; - if (!object || !object->isWidgetType()) - return iface; - QWidget *widget = static_cast(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")) { - QAccessible::Role role = QAccessible::NoRole; -#ifndef QT_NO_MENU - QToolButton *tb = qobject_cast(widget); - if (!tb->menu()) - role = tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton; - else if (tb->popupMode() == QToolButton::DelayedPopup) - role = QAccessible::ButtonDropDown; - else -#endif - role = QAccessible::ButtonMenu; - iface = new QAccessibleToolButton(widget, role); -#endif // QT_NO_TOOLBUTTON - } else if (classname == QLatin1String("QCheckBox")) { - iface = new QAccessibleButton(widget, QAccessible::CheckBox); - } else if (classname == QLatin1String("QRadioButton")) { - iface = new QAccessibleButton(widget, QAccessible::RadioButton); - } else if (classname == QLatin1String("QPushButton")) { - QAccessible::Role role = QAccessible::NoRole; - QPushButton *pb = qobject_cast(widget); -#ifndef QT_NO_MENU - if (pb->menu()) - role = QAccessible::ButtonMenu; - else -#endif - if (pb->isCheckable()) - role = QAccessible::CheckBox; - else - role = QAccessible::PushButton; - iface = new QAccessibleButton(widget, role); - } else if (classname == QLatin1String("QAbstractButton")) { - iface = new QAccessibleButton(widget, QAccessible::PushButton); - } else if (classname == QLatin1String("QDialog")) { - iface = new QAccessibleWidget(widget, QAccessible::Dialog); - } else if (classname == QLatin1String("QMessageBox")) { - iface = new QAccessibleWidget(widget, QAccessible::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); -#ifndef QT_NO_GROUPBOX - } else if (classname == QLatin1String("QGroupBox")) { - iface = new QAccessibleGroupBox(widget); -#endif - } else if (classname == QLatin1String("QStatusBar")) { - iface = new QAccessibleDisplay(widget); -#ifndef QT_NO_PROGRESSBAR - } else if (classname == QLatin1String("QProgressBar")) { - iface = new QAccessibleProgressBar(widget); -#endif - } else if (classname == QLatin1String("QToolBar")) { - iface = new QAccessibleWidget(widget, QAccessible::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); -#endif -#ifndef QT_NO_ITEMVIEWS - } else if (classname == QLatin1String("QTreeView")) { - iface = new QAccessibleTree(widget); - } else if (classname == QLatin1String("QTableView") || classname == QLatin1String("QListView")) { - iface = new QAccessibleTable(widget); - // ### This should be cleaned up. We return the parent for the scrollarea to hide it. -#endif // QT_NO_ITEMVIEWS -#ifndef QT_NO_TABBAR - } else if (classname == QLatin1String("QTabBar")) { - iface = new QAccessibleTabBar(widget); -#endif - } else if (classname == QLatin1String("QSizeGrip")) { - iface = new QAccessibleWidget(widget, QAccessible::Grip); -#ifndef QT_NO_SPLITTER - } else if (classname == QLatin1String("QSplitter")) { - iface = new QAccessibleWidget(widget, QAccessible::Splitter); - } else if (classname == QLatin1String("QSplitterHandle")) { - iface = new QAccessibleWidget(widget, QAccessible::Grip); -#endif -#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR) - } else if (classname == QLatin1String("QTextEdit")) { - iface = new QAccessibleTextEdit(widget); - } else if (classname == QLatin1String("QPlainTextEdit")) { - iface = new QAccessiblePlainTextEdit(widget); -#endif - } else if (classname == QLatin1String("QTipLabel")) { - iface = new QAccessibleDisplay(widget, QAccessible::ToolTip); - } else if (classname == QLatin1String("QFrame")) { - iface = new QAccessibleWidget(widget, QAccessible::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 - } 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 QAccessibleWidget(widget, QAccessible::Border); -#endif -#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) - } 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 - - } else if (classname == QLatin1String("QDesktopScreenWidget")) { - iface = 0; - } else if (classname == QLatin1String("QWidget")) { - iface = new QAccessibleWidget(widget); - } else if (classname == QLatin1String("QWindowContainer")) { - iface = new QAccessibleWindowContainer(widget); - } - - return iface; -} - - -QT_END_NAMESPACE - -#include "main.moc" - -#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp deleted file mode 100644 index 39ac335131..0000000000 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qaccessiblemenu.h" - -#include -#include -#include -#include - -#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); - -QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action) -{ - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action); - if (!iface) { - iface = new QAccessibleMenuItem(menu, action); - QAccessible::registerAccessibleInterface(iface); - } - return iface; -} - -QAccessibleMenu::QAccessibleMenu(QWidget *w) -: QAccessibleWidget(w) -{ - Q_ASSERT(menu()); -} - -QMenu *QAccessibleMenu::menu() const -{ - return qobject_cast(object()); -} - -int QAccessibleMenu::childCount() const -{ - return menu()->actions().count(); -} - -QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const -{ - QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y))); - if(act && act->isSeparator()) - act = 0; - return act ? getOrCreateMenu(menu(), act) : 0; -} - -QString QAccessibleMenu::text(QAccessible::Text t) const -{ - QString tx = QAccessibleWidget::text(t); - if (!tx.isEmpty()) - return tx; - - if (t == QAccessible::Name) - return menu()->windowTitle(); - return tx; -} - -QAccessible::Role QAccessibleMenu::role() const -{ - return QAccessible::PopupMenu; -} - -QAccessibleInterface *QAccessibleMenu::child(int index) const -{ - if (index < childCount()) - return getOrCreateMenu(menu(), menu()->actions().at(index)); - return 0; -} - -QAccessibleInterface *QAccessibleMenu::parent() const -{ - if (QAction *menuAction = menu()->menuAction()) { - QList parentCandidates; - parentCandidates << menu()->parentWidget(); - parentCandidates << menuAction->associatedWidgets(); - foreach (QWidget *w, parentCandidates) { - if (qobject_cast(w) || qobject_cast(w)) { - if (w->actions().indexOf(menuAction) != -1) - return getOrCreateMenu(w, menuAction); - } - } - } - return QAccessibleWidget::parent(); -} - -int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const -{ - QAccessible::Role r = child->role(); - if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) { - return menu()->actions().indexOf(qobject_cast(child->object())); - } - return -1; -} - -#ifndef QT_NO_MENUBAR -QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w) - : QAccessibleWidget(w, QAccessible::MenuBar) -{ - Q_ASSERT(menuBar()); -} - -QMenuBar *QAccessibleMenuBar::menuBar() const -{ - return qobject_cast(object()); -} - -int QAccessibleMenuBar::childCount() const -{ - return menuBar()->actions().count(); -} - -QAccessibleInterface *QAccessibleMenuBar::child(int index) const -{ - if (index < childCount()) { - return getOrCreateMenu(menuBar(), menuBar()->actions().at(index)); - } - return 0; -} - -int QAccessibleMenuBar::indexOfChild(const QAccessibleInterface *child) const -{ - QAccessible::Role r = child->role(); - if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) { - return menuBar()->actions().indexOf(qobject_cast(child->object())); - } - return -1; -} - -#endif // QT_NO_MENUBAR - -QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action) -: m_action(action), m_owner(owner) -{ -} - -QAccessibleMenuItem::~QAccessibleMenuItem() -{} - -QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const -{ - for (int i = childCount() - 1; i >= 0; --i) { - QAccessibleInterface *childInterface = child(i); - if (childInterface->rect().contains(x,y)) { - return childInterface; - } - } - return 0; -} - -int QAccessibleMenuItem::childCount() const -{ - return m_action->menu() ? 1 : 0; -} - -int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const -{ - if (child && child->role() == QAccessible::PopupMenu && child->object() == m_action->menu()) - return 0; - return -1; -} - -bool QAccessibleMenuItem::isValid() const -{ - return m_action && m_owner ? true : false; -} - -QAccessibleInterface *QAccessibleMenuItem::parent() const -{ - return QAccessible::queryAccessibleInterface(owner()); -} - -QAccessibleInterface *QAccessibleMenuItem::child(int index) const -{ - if (index == 0 && action()->menu()) - return QAccessible::queryAccessibleInterface(action()->menu()); - return 0; -} - -void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::ActionInterface) - return static_cast(this); - return 0; -} - -QObject *QAccessibleMenuItem::object() const -{ - return m_action; -} - -QRect QAccessibleMenuItem::rect() const -{ - QRect rect; - QWidget *own = owner(); -#ifndef QT_NO_MENUBAR - if (QMenuBar *menuBar = qobject_cast(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(own)) { - rect = menu->actionGeometry(m_action); - QPoint globalPos = menu->mapToGlobal(QPoint(0,0)); - rect = rect.translated(globalPos); - } - return rect; -} - -QAccessible::Role QAccessibleMenuItem::role() const -{ - return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem; -} - -void QAccessibleMenuItem::setText(QAccessible::Text /*t*/, const QString & /*text */) -{ -} - -QAccessible::State QAccessibleMenuItem::state() const -{ - QAccessible::State s; - QWidget *own = owner(); - - if (own && (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false)) { - s.invisible = true; - } - - if (QMenu *menu = qobject_cast(own)) { - if (menu->activeAction() == m_action) - s.focused = true; -#ifndef QT_NO_MENUBAR - } else if (QMenuBar *menuBar = qobject_cast(own)) { - if (menuBar->activeAction() == m_action) - s.focused = true; -#endif - } - if (own && own->style()->styleHint(QStyle::SH_Menu_MouseTracking)) - s.hotTracked = true; - if (m_action->isSeparator() || !m_action->isEnabled()) - s.disabled = true; - if (m_action->isChecked()) - s.checked = true; - - return s; -} - -QString QAccessibleMenuItem::text(QAccessible::Text t) const -{ - QString str; - switch (t) { - case QAccessible::Name: - str = m_action->text(); - str = qt_accStripAmp(str); - break; - case QAccessible::Accelerator: { -#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; -} - -QStringList QAccessibleMenuItem::actionNames() const -{ - QStringList actions; - if (!m_action || m_action->isSeparator()) - return actions; - - if (m_action->menu()) { - actions << showMenuAction(); - } else { - actions << pressAction(); - } - return actions; -} - -void QAccessibleMenuItem::doAction(const QString &actionName) -{ - if (!m_action->isEnabled()) - return; - - if (actionName == pressAction()) { - m_action->trigger(); - } else if (actionName == showMenuAction()) { - if (QMenuBar *bar = qobject_cast(owner())) { - if (m_action->menu() && m_action->menu()->isVisible()) { - m_action->menu()->hide(); - } else { - bar->setActiveAction(m_action); - } - } else if (QMenu *menu = qobject_cast(owner())){ - if (m_action->menu() && m_action->menu()->isVisible()) { - m_action->menu()->hide(); - } else { - menu->setActiveAction(m_action); - } - } - } -} - -QStringList QAccessibleMenuItem::keyBindingsForAction(const QString &) const -{ - return QStringList(); -} - - -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 deleted file mode 100644 index e8c9f8af3a..0000000000 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QACCESSIBLEMENU_H -#define QACCESSIBLEMENU_H - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -#ifndef QT_NO_MENU -class QMenu; -class QMenuBar; -class QAction; - -class QAccessibleMenu : public QAccessibleWidget -{ -public: - explicit QAccessibleMenu(QWidget *w); - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - int indexOfChild( const QAccessibleInterface *child ) const Q_DECL_OVERRIDE; - -protected: - QMenu *menu() const; -}; - -#ifndef QT_NO_MENUBAR -class QAccessibleMenuBar : public QAccessibleWidget -{ -public: - explicit QAccessibleMenuBar(QWidget *w); - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - -protected: - QMenuBar *menuBar() const; -}; -#endif // QT_NO_MENUBAR - - -class QAccessibleMenuItem : public QAccessibleInterface, public QAccessibleActionInterface -{ -public: - explicit QAccessibleMenuItem(QWidget *owner, QAction *w); - - ~QAccessibleMenuItem(); - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface * child) const Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - QObject * object() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - // QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - - QWidget *owner() const; -protected: - QAction *action() const; -private: - QAction *m_action; - QPointer 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 deleted file mode 100644 index 71d22eabc4..0000000000 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ /dev/null @@ -1,1020 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $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 "qplaintextedit.h" -#include "qtextboundaryfinder.h" -#include "qscrollbar.h" -#include "qdebug.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_ACCESSIBILITY - -QT_BEGIN_NAMESPACE - -QString Q_GUI_EXPORT qt_accStripAmp(const QString &text); -QString Q_GUI_EXPORT qt_accHotKey(const QString &text); - -QList childWidgets(const QWidget *widget, bool includeTopLevel) -{ - if (widget == 0) - return QList(); - QList list = widget->children(); - QList widgets; - for (int i = 0; i < list.size(); ++i) { - QWidget *w = qobject_cast(list.at(i)); - if (!w) - continue; - QString objectName = w->objectName(); - if ((includeTopLevel || !w->isWindow()) - && !qobject_cast(w) - && !qobject_cast(w) - && objectName != QLatin1String("qt_rubberband") - && objectName != QLatin1String("qt_qmainwindow_extended_splitter")) { - widgets.append(w); - } - } - return widgets; -} - -#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR) - -QAccessiblePlainTextEdit::QAccessiblePlainTextEdit(QWidget* o) - :QAccessibleTextWidget(o) -{ - Q_ASSERT(widget()->inherits("QPlainTextEdit")); -} - -QPlainTextEdit* QAccessiblePlainTextEdit::plainTextEdit() const -{ - return static_cast(widget()); -} - -QString QAccessiblePlainTextEdit::text(QAccessible::Text t) const -{ - if (t == QAccessible::Value) - return plainTextEdit()->toPlainText(); - - return QAccessibleWidget::text(t); -} - -void QAccessiblePlainTextEdit::setText(QAccessible::Text t, const QString &text) -{ - if (t != QAccessible::Value) { - QAccessibleWidget::setText(t, text); - return; - } - if (plainTextEdit()->isReadOnly()) - return; - - plainTextEdit()->setPlainText(text); -} - -QAccessible::State QAccessiblePlainTextEdit::state() const -{ - QAccessible::State st = QAccessibleTextWidget::state(); - if (plainTextEdit()->isReadOnly()) - st.readOnly = true; - else - st.editable = true; - return st; -} - -void *QAccessiblePlainTextEdit::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::TextInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - -QPoint QAccessiblePlainTextEdit::scrollBarPosition() const -{ - QPoint result; - result.setX(plainTextEdit()->horizontalScrollBar() ? plainTextEdit()->horizontalScrollBar()->sliderPosition() : 0); - result.setY(plainTextEdit()->verticalScrollBar() ? plainTextEdit()->verticalScrollBar()->sliderPosition() : 0); - return result; -} - -QTextCursor QAccessiblePlainTextEdit::textCursor() const -{ - return plainTextEdit()->textCursor(); -} - -void QAccessiblePlainTextEdit::setTextCursor(const QTextCursor &textCursor) -{ - plainTextEdit()->setTextCursor(textCursor); -} - -QTextDocument* QAccessiblePlainTextEdit::textDocument() const -{ - return plainTextEdit()->document(); -} - -QWidget* QAccessiblePlainTextEdit::viewport() const -{ - return plainTextEdit()->viewport(); -} - -void QAccessiblePlainTextEdit::scrollToSubstring(int startIndex, int endIndex) -{ - //TODO: Not implemented - Q_UNUSED(startIndex); - Q_UNUSED(endIndex); -} - - -/*! - \class QAccessibleTextEdit - \brief The QAccessibleTextEdit class implements the QAccessibleInterface for richtext editors. - \internal -*/ - -/*! - \fn QAccessibleTextEdit::QAccessibleTextEdit(QWidget *widget) - - Constructs a QAccessibleTextEdit object for a \a widget. -*/ -QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o) -: QAccessibleTextWidget(o, QAccessible::EditableText) -{ - Q_ASSERT(widget()->inherits("QTextEdit")); -} - -/*! Returns the text edit. */ -QTextEdit *QAccessibleTextEdit::textEdit() const -{ - return static_cast(widget()); -} - -QTextCursor QAccessibleTextEdit::textCursor() const -{ - return textEdit()->textCursor(); -} - -QTextDocument *QAccessibleTextEdit::textDocument() const -{ - return textEdit()->document(); -} - -void QAccessibleTextEdit::setTextCursor(const QTextCursor &textCursor) -{ - textEdit()->setTextCursor(textCursor); -} - -QWidget *QAccessibleTextEdit::viewport() const -{ - return textEdit()->viewport(); -} - -QPoint QAccessibleTextEdit::scrollBarPosition() const -{ - QPoint result; - result.setX(textEdit()->horizontalScrollBar() ? textEdit()->horizontalScrollBar()->sliderPosition() : 0); - result.setY(textEdit()->verticalScrollBar() ? textEdit()->verticalScrollBar()->sliderPosition() : 0); - return result; -} - -QString QAccessibleTextEdit::text(QAccessible::Text t) const -{ - if (t == QAccessible::Value) - return textEdit()->toPlainText(); - - return QAccessibleWidget::text(t); -} - -void QAccessibleTextEdit::setText(QAccessible::Text t, const QString &text) -{ - if (t != QAccessible::Value) { - QAccessibleWidget::setText(t, text); - return; - } - if (textEdit()->isReadOnly()) - return; - - textEdit()->setText(text); -} - -QAccessible::State QAccessibleTextEdit::state() const -{ - QAccessible::State st = QAccessibleTextWidget::state(); - if (textEdit()->isReadOnly()) - st.readOnly = true; - else - st.editable = true; - return st; -} - -void *QAccessibleTextEdit::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::TextInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - -void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex) -{ - QTextEdit *edit = textEdit(); - - QTextCursor cursor = textCursor(); - 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!"); -} - -#endif // QT_NO_TEXTEDIT && QT_NO_CURSOR - -#ifndef QT_NO_STACKEDWIDGET -// ======================= QAccessibleStackedWidget ====================== -QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::LayeredPane) -{ - Q_ASSERT(qobject_cast(widget)); -} - -QAccessibleInterface *QAccessibleStackedWidget::childAt(int x, int y) const -{ - if (!stackedWidget()->isVisible()) - return 0; - QWidget *currentWidget = stackedWidget()->currentWidget(); - if (!currentWidget) - return 0; - QPoint position = currentWidget->mapFromGlobal(QPoint(x, y)); - if (currentWidget->rect().contains(position)) - return child(stackedWidget()->currentIndex()); - return 0; -} - -int QAccessibleStackedWidget::childCount() const -{ - return stackedWidget()->count(); -} - -int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const -{ - if (!child) - return -1; - - QWidget *widget = qobject_cast(child->object()); - return stackedWidget()->indexOf(widget); -} - -QAccessibleInterface *QAccessibleStackedWidget::child(int index) const -{ - if (index < 0 || index >= stackedWidget()->count()) - return 0; - return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index)); -} - -QStackedWidget *QAccessibleStackedWidget::stackedWidget() const -{ - return static_cast(object()); -} -#endif // QT_NO_STACKEDWIDGET - -#ifndef QT_NO_TOOLBOX -// ======================= QAccessibleToolBox ====================== -QAccessibleToolBox::QAccessibleToolBox(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::LayeredPane) -{ - Q_ASSERT(qobject_cast(widget)); -} - -QToolBox * QAccessibleToolBox::toolBox() const -{ - return static_cast(object()); -} -#endif // QT_NO_TOOLBOX - -// ======================= QAccessibleMdiArea ====================== -#ifndef QT_NO_MDIAREA -QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::LayeredPane) -{ - Q_ASSERT(qobject_cast(widget)); -} - -int QAccessibleMdiArea::childCount() const -{ - return mdiArea()->subWindowList().count(); -} - -QAccessibleInterface *QAccessibleMdiArea::child(int index) const -{ - QList subWindows = mdiArea()->subWindowList(); - QWidget *targetObject = subWindows.value(index); - if (!targetObject) - return 0; - return QAccessible::queryAccessibleInterface(targetObject); -} - - -int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const -{ - if (!child || !child->object() || mdiArea()->subWindowList().isEmpty()) - return -1; - if (QMdiSubWindow *window = qobject_cast(child->object())) { - return mdiArea()->subWindowList().indexOf(window); - } - return -1; -} - -QMdiArea *QAccessibleMdiArea::mdiArea() const -{ - return static_cast(object()); -} - -// ======================= QAccessibleMdiSubWindow ====================== -QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Window) -{ - Q_ASSERT(qobject_cast(widget)); -} - -QString QAccessibleMdiSubWindow::text(QAccessible::Text textType) const -{ - if (textType == QAccessible::Name) { - QString title = mdiSubWindow()->windowTitle(); - title.replace(QLatin1String("[*]"), QLatin1String("")); - return title; - } - return QAccessibleWidget::text(textType); -} - -void QAccessibleMdiSubWindow::setText(QAccessible::Text textType, const QString &text) -{ - if (textType == QAccessible::Name) - mdiSubWindow()->setWindowTitle(text); - else - QAccessibleWidget::setText(textType, text); -} - -QAccessible::State QAccessibleMdiSubWindow::state() const -{ - QAccessible::State state; - state.focusable = true; - if (!mdiSubWindow()->isMaximized()) { - state.movable = true; - state.sizeable = true; - } - if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget()) - || QApplication::focusWidget() == mdiSubWindow()) - state.focused = true; - if (!mdiSubWindow()->isVisible()) - state.invisible = true; - if (const QWidget *parent = mdiSubWindow()->parentWidget()) - if (!parent->contentsRect().contains(mdiSubWindow()->geometry())) - state.offscreen = true; - if (!mdiSubWindow()->isEnabled()) - state.disabled = true; - return state; -} - -int QAccessibleMdiSubWindow::childCount() const -{ - if (mdiSubWindow()->widget()) - return 1; - return 0; -} - -QAccessibleInterface *QAccessibleMdiSubWindow::child(int index) const -{ - QMdiSubWindow *source = mdiSubWindow(); - if (index != 0 || !source->widget()) - return 0; - - return QAccessible::queryAccessibleInterface(source->widget()); -} - -int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const -{ - if (child && child->object() && child->object() == mdiSubWindow()->widget()) - return 0; - return -1; -} - -QRect QAccessibleMdiSubWindow::rect() const -{ - if (mdiSubWindow()->isHidden()) - return QRect(); - if (!mdiSubWindow()->parent()) - return QAccessibleWidget::rect(); - const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0)); - return QRect(pos, mdiSubWindow()->size()); -} - -QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const -{ - return static_cast(object()); -} -#endif // QT_NO_MDIAREA - -#ifndef QT_NO_DIALOGBUTTONBOX -// ======================= QAccessibleDialogButtonBox ====================== -QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Grouping) -{ - Q_ASSERT(qobject_cast(widget)); -} - -#endif // QT_NO_DIALOGBUTTONBOX - -#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) -QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget) - : QAccessibleTextEdit(widget) -{ - Q_ASSERT(qobject_cast(widget)); -} - -QAccessible::Role QAccessibleTextBrowser::role() const -{ - return QAccessible::StaticText; -} -#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR - -#ifndef QT_NO_CALENDARWIDGET -// ===================== QAccessibleCalendarWidget ======================== -QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Table) -{ - Q_ASSERT(qobject_cast(widget)); -} - -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(child->object())) - return childCount() - 1; // FIXME - return 0; -} - -QAccessibleInterface *QAccessibleCalendarWidget::child(int index) const -{ - if (index < 0 || index >= childCount()) - return 0; - - if (childCount() > 1 && index == 0) - return QAccessible::queryAccessibleInterface(navigationBar()); - - return QAccessible::queryAccessibleInterface(calendarView()); -} - -QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const -{ - return static_cast(object()); -} - -QAbstractItemView *QAccessibleCalendarWidget::calendarView() const -{ - foreach (QObject *child, calendarWidget()->children()) { - if (child->objectName() == QLatin1String("qt_calendar_calendarview")) - return static_cast(child); - } - return 0; -} - -QWidget *QAccessibleCalendarWidget::navigationBar() const -{ - foreach (QObject *child, calendarWidget()->children()) { - if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) - return static_cast(child); - } - return 0; -} -#endif // QT_NO_CALENDARWIDGET - -#ifndef QT_NO_DOCKWIDGET - -// Dock Widget - order of children: -// - Content widget -// - Float button -// - Close button -// If there is a custom title bar widget, that one becomes child 1, after the content 0 -// (in that case the buttons are ignored) -QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Window) -{ -} - -QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const -{ - return qobject_cast(dockWidget()->layout()); -} - -int QAccessibleDockWidget::childCount() const -{ - if (dockWidget()->titleBarWidget()) { - return dockWidget()->widget() ? 2 : 1; - } - return dockWidgetLayout()->count(); -} - -QAccessibleInterface *QAccessibleDockWidget::child(int index) const -{ - if (dockWidget()->titleBarWidget()) { - if ((!dockWidget()->widget() && index == 0) || (index == 1)) - return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget()); - if (index == 0) - return QAccessible::queryAccessibleInterface(dockWidget()->widget()); - } else { - QLayoutItem *item = dockWidgetLayout()->itemAt(index); - if (item) - return QAccessible::queryAccessibleInterface(item->widget()); - } - return 0; -} - -int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const -{ - if (!child || !child->object() || child->object()->parent() != object()) - return -1; - - if (dockWidget()->titleBarWidget() == child->object()) { - return dockWidget()->widget() ? 1 : 0; - } - - return dockWidgetLayout()->indexOf(qobject_cast(child->object())); -} - -QRect QAccessibleDockWidget::rect() const -{ - QRect rect; - - if (dockWidget()->isFloating()) { - rect = dockWidget()->frameGeometry(); - } else { - rect = dockWidget()->rect(); - rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); - } - - return rect; -} - -QDockWidget *QAccessibleDockWidget::dockWidget() const -{ - return static_cast(object()); -} - -QString QAccessibleDockWidget::text(QAccessible::Text t) const -{ - if (t == QAccessible::Name) { - return qt_accStripAmp(dockWidget()->windowTitle()); - } - return QString(); -} -#endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_CURSOR - -QAccessibleTextWidget::QAccessibleTextWidget(QWidget *o, QAccessible::Role r, const QString &name): - QAccessibleWidget(o, r, name) -{ - -} - -QAccessible::State QAccessibleTextWidget::state() const -{ - QAccessible::State s = QAccessibleWidget::state(); - s.multiLine = true; - return s; -} - -QRect QAccessibleTextWidget::characterRect(int offset) const -{ - QTextBlock block = textDocument()->findBlock(offset); - if (!block.isValid()) - return QRect(); - - QTextLayout *layout = block.layout(); - QPointF layoutPosition = layout->position(); - int relativeOffset = offset - block.position(); - QTextLine line = layout->lineForTextPosition(relativeOffset); - - QRect r; - - if (line.isValid()) { - qreal x = line.cursorToX(relativeOffset); - QFontMetrics fm(textCursor().charFormat().font()); - const QString ch = text(offset, offset + 1); - if (!ch.isEmpty()) { - int w = fm.width(ch); - int h = fm.height(); - r = QRect(layoutPosition.x() + x, layoutPosition.y() + line.y(), - w, h); - r.moveTo(viewport()->mapToGlobal(r.topLeft())); - } - r.translate(-scrollBarPosition()); - } - - return r; -} - -int QAccessibleTextWidget::offsetAtPoint(const QPoint &point) const -{ - QPoint p = viewport()->mapFromGlobal(point); - // convert to document coordinates - p += scrollBarPosition(); - return textDocument()->documentLayout()->hitTest(p, Qt::ExactHit); -} - -int QAccessibleTextWidget::selectionCount() const -{ - return textCursor().hasSelection() ? 1 : 0; -} - -QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *endOffset) const -{ - /* The list of attributes can be found at: - http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes - */ - - if (offset >= characterCount()) { - *startOffset = -1; - *endOffset = -1; - return QString(); - } - - QMap attrs; - - QTextCursor cursor = textCursor(); - - //cursor.charFormat returns the format of the previous character - cursor.setPosition(offset + 1); - QTextCharFormat charFormat = cursor.charFormat(); - - cursor.setPosition(offset); - QTextBlockFormat blockFormat = cursor.blockFormat(); - - QTextCharFormat charFormatComp; - QTextBlockFormat blockFormatComp; - - *startOffset = offset; - cursor.setPosition(*startOffset); - while (*startOffset > 0) { - charFormatComp = cursor.charFormat(); - cursor.setPosition(*startOffset - 1); - blockFormatComp = cursor.blockFormat(); - if ((charFormat == charFormatComp) && (blockFormat == blockFormatComp)) - (*startOffset)--; - else - break; - } - - int limit = characterCount() + 1; - *endOffset = offset + 1; - cursor.setPosition(*endOffset); - while (*endOffset < limit) { - blockFormatComp = cursor.blockFormat(); - cursor.setPosition(*endOffset + 1); - charFormatComp = cursor.charFormat(); - if ((charFormat == charFormatComp) && (cursor.blockFormat() == blockFormatComp)) - (*endOffset)++; - else - break; - } - - QString family = charFormat.fontFamily(); - if (!family.isEmpty()) { - family = family.replace('\\',"\\\\"); - family = family.replace(':',"\\:"); - family = family.replace(',',"\\,"); - family = family.replace('=',"\\="); - family = family.replace(';',"\\;"); - family = family.replace('\"',"\\\""); - attrs["font-family"] = '"'+family+'"'; - } - - int fontSize = int(charFormat.fontPointSize()); - if (fontSize) - attrs["font-size"] = QString::number(fontSize).append("pt"); - - //Different weight values are not handled - attrs["font-weight"] = (charFormat.fontWeight() > QFont::Normal) ? "bold" : "normal"; - - QFont::Style style = charFormat.font().style(); - attrs["font-style"] = (style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal"); - - attrs["text-underline-style"] = charFormat.font().underline() ? "solid" : "none"; - - QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment(); - attrs["text-position"] = (alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" ); - - QBrush background = charFormat.background(); - if (background.style() == Qt::SolidPattern) { - attrs["background-color"] = QString("rgb(%1,%2,%3)").arg(background.color().red()).arg(background.color().green()).arg(background.color().blue()); - } - - QBrush foreground = charFormat.foreground(); - if (foreground.style() == Qt::SolidPattern) { - attrs["color"] = QString("rgb(%1,%2,%3)").arg(foreground.color().red()).arg(foreground.color().green()).arg(foreground.color().blue()); - } - - switch (blockFormat.alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)) { - case Qt::AlignLeft: - attrs["text-align"] = "left"; - break; - case Qt::AlignRight: - attrs["text-align"] = "right"; - break; - case Qt::AlignHCenter: - attrs["text-align"] = "center"; - break; - case Qt::AlignJustify: - attrs["text-align"] = "left"; - break; - } - - QString result; - foreach (const QString &attributeName, attrs.keys()) { - result.append(attributeName).append(':').append(attrs[attributeName]).append(';'); - } - - return result; -} - -int QAccessibleTextWidget::cursorPosition() const -{ - return textCursor().position(); -} - -void QAccessibleTextWidget::selection(int selectionIndex, int *startOffset, int *endOffset) const -{ - *startOffset = *endOffset = 0; - QTextCursor cursor = textCursor(); - - if (selectionIndex != 0 || !cursor.hasSelection()) - return; - - *startOffset = cursor.selectionStart(); - *endOffset = cursor.selectionEnd(); -} - -QString QAccessibleTextWidget::text(int startOffset, int endOffset) const -{ - QTextCursor cursor(textCursor()); - - cursor.setPosition(startOffset, QTextCursor::MoveAnchor); - cursor.setPosition(endOffset, QTextCursor::KeepAnchor); - - return cursor.selectedText(); -} - -QPoint QAccessibleTextWidget::scrollBarPosition() const -{ - return QPoint(0, 0); -} - - -QString QAccessibleTextWidget::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const -{ - Q_ASSERT(startOffset); - Q_ASSERT(endOffset); - - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - QPair boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - cursor.setPosition(boundaries.first - 1); - boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - - *startOffset = boundaries.first; - *endOffset = boundaries.second; - - return text(boundaries.first, boundaries.second); - } - - -QString QAccessibleTextWidget::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const -{ - Q_ASSERT(startOffset); - Q_ASSERT(endOffset); - - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - QPair boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - cursor.setPosition(boundaries.second); - boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - - *startOffset = boundaries.first; - *endOffset = boundaries.second; - - return text(boundaries.first, boundaries.second); -} - -QString QAccessibleTextWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const -{ - Q_ASSERT(startOffset); - Q_ASSERT(endOffset); - - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - QPair boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - - *startOffset = boundaries.first; - *endOffset = boundaries.second; - - return text(boundaries.first, boundaries.second); -} - -void QAccessibleTextWidget::setCursorPosition(int position) -{ - QTextCursor cursor = textCursor(); - cursor.setPosition(position); - setTextCursor(cursor); -} - -void QAccessibleTextWidget::addSelection(int startOffset, int endOffset) -{ - setSelection(0, startOffset, endOffset); -} - -void QAccessibleTextWidget::removeSelection(int selectionIndex) -{ - if (selectionIndex != 0) - return; - - QTextCursor cursor = textCursor(); - cursor.clearSelection(); - setTextCursor(cursor); -} - -void QAccessibleTextWidget::setSelection(int selectionIndex, int startOffset, int endOffset) -{ - if (selectionIndex != 0) - return; - - QTextCursor cursor = textCursor(); - cursor.setPosition(startOffset, QTextCursor::MoveAnchor); - cursor.setPosition(endOffset, QTextCursor::KeepAnchor); - setTextCursor(cursor); -} - -int QAccessibleTextWidget::characterCount() const -{ - QTextCursor cursor = textCursor(); - cursor.movePosition(QTextCursor::End); - return cursor.position(); -} - -QTextCursor QAccessibleTextWidget::textCursorForRange(int startOffset, int endOffset) const -{ - QTextCursor cursor = textCursor(); - cursor.setPosition(startOffset, QTextCursor::MoveAnchor); - cursor.setPosition(endOffset, QTextCursor::KeepAnchor); - - return cursor; -} - -void QAccessibleTextWidget::deleteText(int startOffset, int endOffset) -{ - QTextCursor cursor = textCursorForRange(startOffset, endOffset); - cursor.removeSelectedText(); -} - -void QAccessibleTextWidget::insertText(int offset, const QString &text) -{ - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - cursor.insertText(text); -} - -void QAccessibleTextWidget::replaceText(int startOffset, int endOffset, const QString &text) -{ - QTextCursor cursor = textCursorForRange(startOffset, endOffset); - cursor.removeSelectedText(); - cursor.insertText(text); -} -#endif // QT_NO_CURSOR - - -#ifndef QT_NO_MAINWINDOW -QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Window) { } - -QAccessibleInterface *QAccessibleMainWindow::child(int index) const -{ - QList kids = childWidgets(mainWindow(), true); - if (index >= 0 && index < kids.count()) { - return QAccessible::queryAccessibleInterface(kids.at(index)); - } - return 0; -} - -int QAccessibleMainWindow::childCount() const -{ - QList kids = childWidgets(mainWindow(), true); - return kids.count(); -} - -int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const -{ - QList kids = childWidgets(mainWindow(), true); - return kids.indexOf(static_cast(iface->object())); -} - -QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const -{ - QWidget *w = widget(); - if (!w->isVisible()) - return 0; - QPoint gp = w->mapToGlobal(QPoint(0, 0)); - if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y)) - return 0; - - 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 QAccessible::queryAccessibleInterface(child); - } - } - return 0; -} - -QMainWindow *QAccessibleMainWindow::mainWindow() const -{ - return qobject_cast(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 deleted file mode 100644 index 3f50010685..0000000000 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ /dev/null @@ -1,314 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QACCESSIBLEWIDGETS_H -#define QACCESSIBLEWIDGETS_H - -#include - -#ifndef QT_NO_ACCESSIBILITY - -#include -#include - -QT_BEGIN_NAMESPACE - -class QTextEdit; -class QStackedWidget; -class QToolBox; -class QMdiArea; -class QMdiSubWindow; -class QRubberBand; -class QTextBrowser; -class QCalendarWidget; -class QAbstractItemView; -class QDockWidget; -class QDockWidgetLayout; -class QMainWindow; -class QPlainTextEdit; -class QTextCursor; -class QTextDocument; - -#ifndef QT_NO_CURSOR -class QAccessibleTextWidget : public QAccessibleWidget, - public QAccessibleTextInterface, - public QAccessibleEditableTextInterface -{ -public: - QAccessibleTextWidget(QWidget *o, QAccessible::Role r = QAccessible::EditableText, const QString &name = QString()); - - QAccessible::State state() const; - - // QAccessibleTextInterface - // selection - void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int selectionCount() const Q_DECL_OVERRIDE; - void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; - void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; - - // cursor - int cursorPosition() const Q_DECL_OVERRIDE; - void setCursorPosition(int position) Q_DECL_OVERRIDE; - - // text - QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; - QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int characterCount() const; - - // character <-> geometry - QRect characterRect(int offset) const Q_DECL_OVERRIDE; - int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; - - QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - - // QAccessibleEditableTextInterface - void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; - void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; - - using QAccessibleWidget::text; - -protected: - QTextCursor textCursorForRange(int startOffset, int endOffset) const; - virtual QPoint scrollBarPosition() const; - // return the current text cursor at the caret position including a potential selection - virtual QTextCursor textCursor() const = 0; - virtual void setTextCursor(const QTextCursor &) = 0; - virtual QTextDocument *textDocument() const = 0; - virtual QWidget *viewport() const = 0; -}; - -#ifndef QT_NO_TEXTEDIT -class QAccessiblePlainTextEdit : public QAccessibleTextWidget -{ -public: - explicit QAccessiblePlainTextEdit(QWidget *o); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - using QAccessibleTextWidget::text; - -protected: - QPlainTextEdit *plainTextEdit() const; - - QPoint scrollBarPosition() const Q_DECL_OVERRIDE; - QTextCursor textCursor() const Q_DECL_OVERRIDE; - void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; - QTextDocument *textDocument() const Q_DECL_OVERRIDE; - QWidget *viewport() const Q_DECL_OVERRIDE; -}; - -class QAccessibleTextEdit : public QAccessibleTextWidget -{ -public: - explicit QAccessibleTextEdit(QWidget *o); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - using QAccessibleTextWidget::text; - -protected: - QTextEdit *textEdit() const; - - QPoint scrollBarPosition() const Q_DECL_OVERRIDE; - QTextCursor textCursor() const Q_DECL_OVERRIDE; - void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; - QTextDocument *textDocument() const Q_DECL_OVERRIDE; - QWidget *viewport() const Q_DECL_OVERRIDE; -}; -#endif // QT_NO_TEXTEDIT -#endif //QT_NO_CURSOR - -class QAccessibleStackedWidget : public QAccessibleWidget -{ -public: - explicit QAccessibleStackedWidget(QWidget *widget); - - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - -protected: - QStackedWidget *stackedWidget() const; -}; - -class QAccessibleToolBox : public QAccessibleWidget -{ -public: - explicit QAccessibleToolBox(QWidget *widget); - -// FIXME we currently expose the toolbox but it is not keyboard navigatable -// and the accessible hierarchy is not exactly beautiful. -// int childCount() const; -// QAccessibleInterface *child(int index) const; -// int indexOfChild(const QAccessibleInterface *child) const; - -protected: - QToolBox *toolBox() const; -}; - -#ifndef QT_NO_MDIAREA -class QAccessibleMdiArea : public QAccessibleWidget -{ -public: - explicit QAccessibleMdiArea(QWidget *widget); - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - -protected: - QMdiArea *mdiArea() const; -}; - -class QAccessibleMdiSubWindow : public QAccessibleWidget -{ -public: - explicit QAccessibleMdiSubWindow(QWidget *widget); - - QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text textType, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - -protected: - QMdiSubWindow *mdiSubWindow() const; -}; -#endif // QT_NO_MDIAREA - -class QAccessibleDialogButtonBox : public QAccessibleWidget -{ -public: - explicit QAccessibleDialogButtonBox(QWidget *widget); -}; - -#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) -class QAccessibleTextBrowser : public QAccessibleTextEdit -{ -public: - explicit QAccessibleTextBrowser(QWidget *widget); - - QAccessible::Role role() const Q_DECL_OVERRIDE; -}; -#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR - -#ifndef QT_NO_CALENDARWIDGET -class QAccessibleCalendarWidget : public QAccessibleWidget -{ -public: - explicit QAccessibleCalendarWidget(QWidget *widget); - - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - -protected: - QCalendarWidget *calendarWidget() const; - -private: - QAbstractItemView *calendarView() const; - QWidget *navigationBar() const; -}; -#endif // QT_NO_CALENDARWIDGET - -#ifndef QT_NO_DOCKWIDGET -class QAccessibleDockWidget: public QAccessibleWidget -{ -public: - explicit QAccessibleDockWidget(QWidget *widget); - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QRect rect () const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - QDockWidget *dockWidget() const; -protected: - QDockWidgetLayout *dockWidgetLayout() const; -}; - -#endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_MAINWINDOW -class QAccessibleMainWindow : public QAccessibleWidget -{ -public: - explicit QAccessibleMainWindow(QWidget *widget); - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - 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 deleted file mode 100644 index f2aa5522e8..0000000000 --- a/src/plugins/accessible/widgets/rangecontrols.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "rangecontrols.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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) -: QAccessibleWidget(w, QAccessible::SpinBox) -{ - Q_ASSERT(abstractSpinBox()); -} - -/*! - Returns the underlying QAbstractSpinBox. -*/ -QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const -{ - return qobject_cast(object()); -} - -QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const -{ - if (t == QAccessible::Value) - return abstractSpinBox()->text(); - return QAccessibleWidget::text(t); -} - -void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::ValueInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - -QVariant QAccessibleAbstractSpinBox::currentValue() const -{ - 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("value", value); -} - -QVariant QAccessibleAbstractSpinBox::maximumValue() const -{ - return abstractSpinBox()->property("maximum"); -} - -QVariant QAccessibleAbstractSpinBox::minimumValue() const -{ - return abstractSpinBox()->property("minimum"); -} - -QVariant QAccessibleAbstractSpinBox::minimumStepSize() const -{ - return abstractSpinBox()->property("stepSize"); -} - -/*! - \class QAccessibleSpinBox - \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets. - \internal - - \ingroup accessibility -*/ - -/*! - 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(object()); -} - - -// ================================== QAccessibleDoubleSpinBox ================================== -QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget) - : QAccessibleAbstractSpinBox(widget) -{ - Q_ASSERT(qobject_cast(widget)); - addControllingSignal(QLatin1String("valueChanged(double)")); - addControllingSignal(QLatin1String("valueChanged(QString)")); -} - -/*! - Returns the underlying QDoubleSpinBox. -*/ -QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const -{ - return static_cast(object()); -} - -QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const -{ - if (textType == QAccessible::Value) - return doubleSpinBox()->textFromValue(doubleSpinBox()->value()); - return QAccessibleWidget::text(textType); -} - -#endif // QT_NO_SPINBOX - -#ifndef QT_NO_SCROLLBAR -/*! - \class QAccessibleScrollBar - \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars. - \internal - - \ingroup accessibility -*/ - -/*! - Constructs a QAccessibleScrollBar object for \a w. - \a name is propagated to the QAccessibleWidget constructor. -*/ -QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w) -: QAccessibleAbstractSlider(w, QAccessible::ScrollBar) -{ - Q_ASSERT(scrollBar()); - addControllingSignal(QLatin1String("valueChanged(int)")); -} - -/*! Returns the scroll bar. */ -QScrollBar *QAccessibleScrollBar::scrollBar() const -{ - return qobject_cast(object()); -} - -QString QAccessibleScrollBar::text(QAccessible::Text t) const -{ - if (t == QAccessible::Value) - return QString::number(scrollBar()->value()); - return QAccessibleAbstractSlider::text(t); -} - -#endif // QT_NO_SCROLLBAR - -#ifndef QT_NO_SLIDER -/*! - \class QAccessibleSlider - \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders. - \internal - - \ingroup accessibility -*/ - -/*! - Constructs a QAccessibleScrollBar object for \a w. - \a name is propagated to the QAccessibleWidget constructor. -*/ -QAccessibleSlider::QAccessibleSlider(QWidget *w) -: QAccessibleAbstractSlider(w) -{ - Q_ASSERT(slider()); - addControllingSignal(QLatin1String("valueChanged(int)")); -} - -/*! Returns the slider. */ -QSlider *QAccessibleSlider::slider() const -{ - return qobject_cast(object()); -} - -QString QAccessibleSlider::text(QAccessible::Text t) const -{ - if (t == QAccessible::Value) - return QString::number(slider()->value()); - - return QAccessibleAbstractSlider::text(t); -} - -QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r) - : QAccessibleWidget(w, r) -{ - Q_ASSERT(qobject_cast(w)); -} - -void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::ValueInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - -QVariant QAccessibleAbstractSlider::currentValue() const -{ - return abstractSlider()->value(); -} - -void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value) -{ - abstractSlider()->setValue(value.toInt()); -} - -QVariant QAccessibleAbstractSlider::maximumValue() const -{ - return abstractSlider()->maximum(); -} - -QVariant QAccessibleAbstractSlider::minimumValue() const -{ - return abstractSlider()->minimum(); -} - -QVariant QAccessibleAbstractSlider::minimumStepSize() const -{ - return abstractSlider()->singleStep(); -} - -QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const -{ - return static_cast(object()); -} - -#endif // QT_NO_SLIDER - -#ifndef QT_NO_DIAL -// ======================================= QAccessibleDial ====================================== -QAccessibleDial::QAccessibleDial(QWidget *widget) - : QAccessibleAbstractSlider(widget, QAccessible::Dial) -{ - Q_ASSERT(qobject_cast(widget)); - addControllingSignal(QLatin1String("valueChanged(int)")); -} - -QString QAccessibleDial::text(QAccessible::Text textType) const -{ - if (textType == QAccessible::Value) - return QString::number(dial()->value()); - - return QAccessibleAbstractSlider::text(textType); -} - -QDial *QAccessibleDial::dial() const -{ - return static_cast(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 deleted file mode 100644 index dd69788bb1..0000000000 --- a/src/plugins/accessible/widgets/rangecontrols.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RANGECONTROLS_H -#define RANGECONTROLS_H - -#include - -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 QAccessibleWidget, public QAccessibleValueInterface // TODO, public QAccessibleActionInterface -{ -public: - explicit QAccessibleAbstractSpinBox(QWidget *w); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleValueInterface - QVariant currentValue() const Q_DECL_OVERRIDE; - void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; - QVariant maximumValue() const Q_DECL_OVERRIDE; - QVariant minimumValue() const Q_DECL_OVERRIDE; - QVariant minimumStepSize() const Q_DECL_OVERRIDE; - - // FIXME Action interface - -protected: - QAbstractSpinBox *abstractSpinBox() const; -}; - -class QAccessibleSpinBox : public QAccessibleAbstractSpinBox -{ -public: - explicit QAccessibleSpinBox(QWidget *w); - -protected: - QSpinBox *spinBox() const; -}; - -class QAccessibleDoubleSpinBox : public QAccessibleAbstractSpinBox -{ -public: - explicit QAccessibleDoubleSpinBox(QWidget *widget); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - -protected: - QDoubleSpinBox *doubleSpinBox() const; -}; -#endif // QT_NO_SPINBOX - -class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface -{ -public: - explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider); - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleValueInterface - QVariant currentValue() const Q_DECL_OVERRIDE; - void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; - QVariant maximumValue() const Q_DECL_OVERRIDE; - QVariant minimumValue() const Q_DECL_OVERRIDE; - QVariant minimumStepSize() const Q_DECL_OVERRIDE; - -protected: - QAbstractSlider *abstractSlider() const; -}; - -#ifndef QT_NO_SCROLLBAR -class QAccessibleScrollBar : public QAccessibleAbstractSlider -{ -public: - explicit QAccessibleScrollBar(QWidget *w); - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - -protected: - QScrollBar *scrollBar() const; -}; -#endif // QT_NO_SCROLLBAR - -#ifndef QT_NO_SLIDER -class QAccessibleSlider : public QAccessibleAbstractSlider -{ -public: - explicit QAccessibleSlider(QWidget *w); - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - -protected: - QSlider *slider() const; -}; -#endif // QT_NO_SLIDER - -#ifndef QT_NO_DIAL -class QAccessibleDial : public QAccessibleAbstractSlider -{ -public: - explicit QAccessibleDial(QWidget *w); - - QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; - -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 deleted file mode 100644 index 893be2df04..0000000000 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ /dev/null @@ -1,886 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "simplewidgets.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef Q_OS_MAC -#include -#endif - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -extern QList 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 QAccessibleWidget constructor. -*/ -QAccessibleButton::QAccessibleButton(QWidget *w, QAccessible::Role role) -: QAccessibleWidget(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(object()); -} - -/*! \reimp */ -QString QAccessibleButton::text(QAccessible::Text t) const -{ - QString str; - switch (t) { - case QAccessible::Accelerator: - { -#ifndef QT_NO_SHORTCUT - QPushButton *pb = qobject_cast(object()); - if (pb && pb->isDefault()) - str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText); -#endif - if (str.isEmpty()) - str = qt_accHotKey(button()->text()); - } - break; - case QAccessible::Name: - str = widget()->accessibleName(); - if (str.isEmpty()) - str = button()->text(); - break; - default: - break; - } - if (str.isEmpty()) - str = QAccessibleWidget::text(t); - return qt_accStripAmp(str); -} - -QAccessible::State QAccessibleButton::state() const -{ - QAccessible::State state = QAccessibleWidget::state(); - - QAbstractButton *b = button(); - QCheckBox *cb = qobject_cast(b); - if (b->isChecked()) - state.checked = true; - else if (cb && cb->checkState() == Qt::PartiallyChecked) - state.checkStateMixed = true; - if (b->isDown()) - state.pressed = true; - QPushButton *pb = qobject_cast(b); - if (pb) { - if (pb->isDefault()) - state.defaultButton = true; -#ifndef QT_NO_MENU - if (pb->menu()) - state.hasPopup = true; -#endif - } - - return state; -} - -QStringList QAccessibleButton::actionNames() const -{ - QStringList names; - if (widget()->isEnabled()) { - switch (role()) { - case QAccessible::ButtonMenu: - names << showMenuAction(); - break; - case QAccessible::RadioButton: - names << toggleAction(); - break; - default: - if (button()->isCheckable()) { - names << toggleAction(); - } else { - names << pressAction(); - } - break; - } - } - names << QAccessibleWidget::actionNames(); - return names; -} - -void QAccessibleButton::doAction(const QString &actionName) -{ - if (!widget()->isEnabled()) - return; - if (actionName == pressAction() || - actionName == showMenuAction()) { -#ifndef QT_NO_MENU - QPushButton *pb = qobject_cast(object()); - if (pb && pb->menu()) - pb->showMenu(); - else -#endif - button()->animateClick(); - } else if (actionName == toggleAction()) { - button()->toggle(); - } else { - QAccessibleWidget::doAction(actionName); - } -} - -QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) const -{ - if (actionName == pressAction()) { -#ifndef QT_NO_SHORTCUT - return QStringList() << button()->shortcut().toString(); -#endif - } - return QStringList(); -} - - -#ifndef QT_NO_TOOLBUTTON -/*! - \class QAccessibleToolButton - \brief The QAccessibleToolButton class implements the QAccessibleInterface for tool buttons. - \internal - - \ingroup accessibility -*/ - -/*! - Creates a QAccessibleToolButton object for \a w. - \a role is propagated to the QAccessibleWidget constructor. -*/ -QAccessibleToolButton::QAccessibleToolButton(QWidget *w, QAccessible::Role role) -: QAccessibleButton(w, role) -{ - Q_ASSERT(toolButton()); -} - -/*! Returns the button. */ -QToolButton *QAccessibleToolButton::toolButton() const -{ - return qobject_cast(object()); -} - -/*! - Returns \c 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 -} - -QAccessible::State QAccessibleToolButton::state() const -{ - QAccessible::State st = QAccessibleButton::state(); - if (toolButton()->autoRaise()) - st.hotTracked = true; -#ifndef QT_NO_MENU - if (toolButton()->menu()) - st.hasPopup = true; -#endif - return st; -} - -int QAccessibleToolButton::childCount() const -{ - return isSplitButton() ? 1 : 0; -} - -QAccessibleInterface *QAccessibleToolButton::child(int index) const -{ -#ifndef QT_NO_MENU - if (index == 0 && toolButton()->menu()) - { - return QAccessible::queryAccessibleInterface(toolButton()->menu()); - } -#endif - return 0; -} - -/*! - \internal - - Returns the button's text label, depending on the text \a t, and - the \a child. -*/ -QString QAccessibleToolButton::text(QAccessible::Text t) const -{ - QString str; - switch (t) { - case QAccessible::Name: - str = toolButton()->accessibleName(); - if (str.isEmpty()) - str = toolButton()->text(); - break; - default: - break; - } - if (str.isEmpty()) - str = QAccessibleButton::text(t); - return qt_accStripAmp(str); -} - -/* - The three different tool button types can have the following actions: -| DelayedPopup | ShowMenuAction + (PressedAction || CheckedAction) | -| MenuButtonPopup | ShowMenuAction + (PressedAction || CheckedAction) | -| InstantPopup | ShowMenuAction | -*/ -QStringList QAccessibleToolButton::actionNames() const -{ - QStringList names; - if (widget()->isEnabled()) { - if (toolButton()->menu()) - names << showMenuAction(); - if (toolButton()->popupMode() != QToolButton::InstantPopup) - names << QAccessibleButton::actionNames(); - } - return names; -} - -void QAccessibleToolButton::doAction(const QString &actionName) -{ - if (!widget()->isEnabled()) - return; - - if (actionName == pressAction()) { - button()->click(); - } else if (actionName == showMenuAction()) { - if (toolButton()->popupMode() != QToolButton::InstantPopup) { - toolButton()->setDown(true); -#ifndef QT_NO_MENU - toolButton()->showMenu(); -#endif - } - } else { - QAccessibleButton::doAction(actionName); - } - -} - -#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 QAccessibleWidget constructor. -*/ -QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role) -: QAccessibleWidget(w, role) -{ -} - -QAccessible::Role QAccessibleDisplay::role() const -{ - QLabel *l = qobject_cast(object()); - if (l) { - if (l->pixmap()) - return QAccessible::Graphic; -#ifndef QT_NO_PICTURE - if (l->picture()) - return QAccessible::Graphic; -#endif -#ifndef QT_NO_MOVIE - if (l->movie()) - return QAccessible::Animation; -#endif -#ifndef QT_NO_PROGRESSBAR - } else if (qobject_cast(object())) { - return QAccessible::ProgressBar; -#endif - } else if (qobject_cast(object())) { - return QAccessible::StatusBar; - } - return QAccessibleWidget::role(); -} - -QString QAccessibleDisplay::text(QAccessible::Text t) const -{ - QString str; - switch (t) { - case QAccessible::Name: - str = widget()->accessibleName(); - if (str.isEmpty()) { - if (qobject_cast(object())) { - QLabel *label = qobject_cast(object()); - str = label->text(); - if (label->textFormat() == Qt::RichText - || (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(str))) { - QTextDocument doc; - doc.setHtml(str); - str = doc.toPlainText(); - } -#ifndef QT_NO_LCDNUMBER - } else if (qobject_cast(object())) { - QLCDNumber *l = qobject_cast(object()); - if (l->digitCount()) - str = QString::number(l->value()); - else - str = QString::number(l->intValue()); -#endif - } else if (qobject_cast(object())) { - return qobject_cast(object())->currentMessage(); - } - } - break; - case QAccessible::Value: -#ifndef QT_NO_PROGRESSBAR - if (qobject_cast(object())) - str = QString::number(qobject_cast(object())->value()); -#endif - break; - default: - break; - } - if (str.isEmpty()) - str = QAccessibleWidget::text(t); - return qt_accStripAmp(str); -} - -/*! \reimp */ -QVector > -QAccessibleDisplay::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const -{ - QVector > rels = QAccessibleWidget::relations(match); - if (match & QAccessible::Labelled) { - QVarLengthArray relatedObjects; - -#ifndef QT_NO_SHORTCUT - if (QLabel *label = qobject_cast(object())) { - relatedObjects.append(label->buddy()); - } -#endif - for (int i = 0; i < relatedObjects.count(); ++i) { - const QAccessible::Relation rel = QAccessible::Labelled; - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i)); - if (iface) - rels.append(qMakePair(iface, rel)); - } - } - return rels; -} - -void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::ImageInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - -/*! \internal */ -QString QAccessibleDisplay::imageDescription() const -{ -#ifndef QT_NO_TOOLTIP - return widget()->toolTip(); -#else - return QString::null; -#endif -} - -/*! \internal */ -QSize QAccessibleDisplay::imageSize() const -{ - QLabel *label = qobject_cast(widget()); - if (!label) - return QSize(); - const QPixmap *pixmap = label->pixmap(); - if (!pixmap) - return QSize(); - return pixmap->size(); -} - -/*! \internal */ -QPoint QAccessibleDisplay::imagePosition() const -{ - QLabel *label = qobject_cast(widget()); - if (!label) - return QPoint(); - const QPixmap *pixmap = label->pixmap(); - if (!pixmap) - return QPoint(); - - return QPoint(label->mapToGlobal(label->pos())); -} - -#ifndef QT_NO_GROUPBOX -QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w) -: QAccessibleWidget(w) -{ -} - -QGroupBox* QAccessibleGroupBox::groupBox() const -{ - return static_cast(widget()); -} - -QString QAccessibleGroupBox::text(QAccessible::Text t) const -{ - QString txt = QAccessibleWidget::text(t); - - if (txt.isEmpty()) { - switch (t) { - case QAccessible::Name: - txt = qt_accStripAmp(groupBox()->title()); - break; - case QAccessible::Description: - txt = qt_accStripAmp(groupBox()->toolTip()); - break; - default: - break; - } - } - - return txt; -} - -QAccessible::State QAccessibleGroupBox::state() const -{ - QAccessible::State st = QAccessibleWidget::state(); - st.checkable = groupBox()->isCheckable(); - st.checked = groupBox()->isChecked(); - return st; -} - -QAccessible::Role QAccessibleGroupBox::role() const -{ - return groupBox()->isCheckable() ? QAccessible::CheckBox : QAccessible::Grouping; -} - -QVector > -QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const -{ - QVector > rels = QAccessibleWidget::relations(match); - - if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) { - const QList kids = childWidgets(widget()); - for (int i = 0; i < kids.count(); ++i) { - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kids.at(i)); - if (iface) - rels.append(qMakePair(iface, QAccessible::Relation(QAccessible::Labelled))); - } - } - return rels; -} - -QStringList QAccessibleGroupBox::actionNames() const -{ - QStringList actions = QAccessibleWidget::actionNames(); - - if (groupBox()->isCheckable()) { - actions.prepend(QAccessibleActionInterface::toggleAction()); - } - return actions; -} - -void QAccessibleGroupBox::doAction(const QString &actionName) -{ - if (actionName == QAccessibleActionInterface::toggleAction()) - groupBox()->setChecked(!groupBox()->isChecked()); -} - -QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const -{ - return QStringList(); -} - -#endif - -#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 QAccessibleWidget constructor. -*/ -QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name) -: QAccessibleWidget(w, QAccessible::EditableText, name) -{ - addControllingSignal(QLatin1String("textChanged(const QString&)")); - addControllingSignal(QLatin1String("returnPressed()")); -} - -/*! Returns the line edit. */ -QLineEdit *QAccessibleLineEdit::lineEdit() const -{ - return qobject_cast(object()); -} - -QString QAccessibleLineEdit::text(QAccessible::Text t) const -{ - QString str; - switch (t) { - case QAccessible::Value: - if (lineEdit()->echoMode() == QLineEdit::Normal) - str = lineEdit()->text(); - break; - default: - break; - } - if (str.isEmpty()) - str = QAccessibleWidget::text(t); - return qt_accStripAmp(str); -} - -void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text) -{ - if (t != QAccessible::Value) { - QAccessibleWidget::setText(t, text); - return; - } - - QString newText = text; - if (lineEdit()->validator()) { - int pos = 0; - if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable) - return; - } - lineEdit()->setText(newText); -} - -QAccessible::State QAccessibleLineEdit::state() const -{ - QAccessible::State state = QAccessibleWidget::state(); - - QLineEdit *l = lineEdit(); - if (l->isReadOnly()) - state.readOnly = true; - else - state.editable = true; - - if (l->echoMode() != QLineEdit::Normal) - state.passwordEdit = true; - state.selectable = true; - if (l->hasSelectedText()) - state.selected = true; - - if (l->contextMenuPolicy() != Qt::NoContextMenu - && l->contextMenuPolicy() != Qt::PreventContextMenu) - state.hasPopup = true; - - return state; -} - -void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::TextInterface) - return static_cast(this); - if (t == QAccessible::EditableTextInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - -void QAccessibleLineEdit::addSelection(int startOffset, int endOffset) -{ - setSelection(0, startOffset, endOffset); -} - -QString QAccessibleLineEdit::attributes(int offset, int *startOffset, int *endOffset) const -{ - // QLineEdit doesn't have text attributes - *startOffset = *endOffset = offset; - return QString(); -} - -int QAccessibleLineEdit::cursorPosition() const -{ - return lineEdit()->cursorPosition(); -} - -QRect QAccessibleLineEdit::characterRect(int offset) const -{ - int x = lineEdit()->d_func()->control->cursorToX(offset); - int y; - lineEdit()->getTextMargins(0, &y, 0, 0); - QFontMetrics fm(lineEdit()->font()); - const QString ch = text(offset, offset + 1); - if (ch.isEmpty()) - return QRect(); - int w = fm.width(ch); - int h = fm.height(); - QRect r(x, y, w, h); - r.moveTo(lineEdit()->mapToGlobal(r.topLeft())); - return r; -} - -int QAccessibleLineEdit::selectionCount() const -{ - return lineEdit()->hasSelectedText() ? 1 : 0; -} - -int QAccessibleLineEdit::offsetAtPoint(const QPoint &point) const -{ - QPoint p = lineEdit()->mapFromGlobal(point); - - return lineEdit()->cursorPositionAt(p); -} - -void QAccessibleLineEdit::selection(int selectionIndex, int *startOffset, int *endOffset) const -{ - *startOffset = *endOffset = 0; - if (selectionIndex != 0) - return; - - *startOffset = lineEdit()->selectionStart(); - *endOffset = *startOffset + lineEdit()->selectedText().count(); -} - -QString QAccessibleLineEdit::text(int startOffset, int endOffset) const -{ - if (startOffset > endOffset) - return QString(); - - if (lineEdit()->echoMode() != QLineEdit::Normal) - return QString(); - - return lineEdit()->text().mid(startOffset, endOffset - startOffset); -} - -QString QAccessibleLineEdit::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const -{ - if (lineEdit()->echoMode() != QLineEdit::Normal) { - *startOffset = *endOffset = -1; - return QString(); - } - return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset); -} - -QString QAccessibleLineEdit::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const -{ - if (lineEdit()->echoMode() != QLineEdit::Normal) { - *startOffset = *endOffset = -1; - return QString(); - } - return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset); -} - -QString QAccessibleLineEdit::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const -{ - if (lineEdit()->echoMode() != QLineEdit::Normal) { - *startOffset = *endOffset = -1; - return QString(); - } - return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset); -} - -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() const -{ - return lineEdit()->text().count(); -} - -void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex) -{ - lineEdit()->setCursorPosition(endIndex); - lineEdit()->setCursorPosition(startIndex); -} - -void QAccessibleLineEdit::deleteText(int startOffset, int endOffset) -{ - lineEdit()->setText(lineEdit()->text().remove(startOffset, endOffset - startOffset)); -} - -void QAccessibleLineEdit::insertText(int offset, const QString &text) -{ - lineEdit()->setText(lineEdit()->text().insert(offset, text)); -} - -void QAccessibleLineEdit::replaceText(int startOffset, int endOffset, const QString &text) -{ - lineEdit()->setText(lineEdit()->text().replace(startOffset, endOffset - startOffset, text)); -} - -#endif // QT_NO_LINEEDIT - -#ifndef QT_NO_PROGRESSBAR -QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o) - : QAccessibleDisplay(o) -{ - Q_ASSERT(progressBar()); -} - -void *QAccessibleProgressBar::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::ValueInterface) - return static_cast(this); - return QAccessibleDisplay::interface_cast(t); -} - -QVariant QAccessibleProgressBar::currentValue() const -{ - return progressBar()->value(); -} - -QVariant QAccessibleProgressBar::maximumValue() const -{ - return progressBar()->maximum(); -} - -QVariant QAccessibleProgressBar::minimumValue() const -{ - return progressBar()->minimum(); -} - -QVariant QAccessibleProgressBar::minimumStepSize() const -{ - // This is arbitrary since any value between min and max is valid. - // Some screen readers (orca use it to calculate how many digits to display though, - // so it makes sense to return a "sensible" value. Providing 100 increments seems ok. - return (progressBar()->maximum() - progressBar()->minimum()) / 100.0; -} - -QProgressBar *QAccessibleProgressBar::progressBar() const -{ - return qobject_cast(object()); -} -#endif - - -QAccessibleWindowContainer::QAccessibleWindowContainer(QWidget *w) - : QAccessibleWidget(w) -{ -} - -int QAccessibleWindowContainer::childCount() const -{ - if (container()->containedWindow()) - return 1; - return 0; -} - -int QAccessibleWindowContainer::indexOfChild(const QAccessibleInterface *child) const -{ - if (child->object() == container()->containedWindow()) - return 0; - return -1; -} - -QAccessibleInterface *QAccessibleWindowContainer::child(int i) const -{ - if (i == 0) - return QAccessible::queryAccessibleInterface(container()->containedWindow()); - return 0; -} - -QWindowContainer *QAccessibleWindowContainer::container() const -{ - return static_cast(widget()); -} - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h deleted file mode 100644 index be19d8324f..0000000000 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SIMPLEWIDGETS_H -#define SIMPLEWIDGETS_H - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -class QAbstractButton; -class QLineEdit; -class QToolButton; -class QGroupBox; -class QProgressBar; - -class QAccessibleButton : public QAccessibleWidget -{ - Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) -public: - QAccessibleButton(QWidget *w, QAccessible::Role r); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - -protected: - QAbstractButton *button() const; -}; - -#ifndef QT_NO_TOOLBUTTON -class QAccessibleToolButton : public QAccessibleButton -{ -public: - QAccessibleToolButton(QWidget *w, QAccessible::Role role); - - QAccessible::State state() const Q_DECL_OVERRIDE; - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - // QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - -protected: - QToolButton *toolButton() const; - - bool isSplitButton() const; -}; -#endif // QT_NO_TOOLBUTTON - -class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface -{ -public: - explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - - QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleImageInterface - QString imageDescription() const Q_DECL_OVERRIDE; - QSize imageSize() const Q_DECL_OVERRIDE; - QPoint imagePosition() const Q_DECL_OVERRIDE; -}; - -#ifndef QT_NO_GROUPBOX -class QAccessibleGroupBox : public QAccessibleWidget -{ -public: - explicit QAccessibleGroupBox(QWidget *w); - - QAccessible::State state() const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; - - //QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &) const Q_DECL_OVERRIDE; - -private: - QGroupBox *groupBox() const; -}; -#endif - -#ifndef QT_NO_LINEEDIT -class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface -{ -public: - explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString()); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; - QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int cursorPosition() const Q_DECL_OVERRIDE; - QRect characterRect(int offset) const Q_DECL_OVERRIDE; - int selectionCount() const Q_DECL_OVERRIDE; - int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; - void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; - QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; - void setCursorPosition(int position) Q_DECL_OVERRIDE; - void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; - int characterCount() const Q_DECL_OVERRIDE; - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - // QAccessibleEditableTextInterface - void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; - void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; -protected: - QLineEdit *lineEdit() const; -}; -#endif // QT_NO_LINEEDIT - -#ifndef QT_NO_PROGRESSBAR -class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface -{ -public: - explicit QAccessibleProgressBar(QWidget *o); - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleValueInterface - QVariant currentValue() const Q_DECL_OVERRIDE; - QVariant maximumValue() const Q_DECL_OVERRIDE; - QVariant minimumValue() const Q_DECL_OVERRIDE; - QVariant minimumStepSize() const Q_DECL_OVERRIDE; - void setCurrentValue(const QVariant &) Q_DECL_OVERRIDE {} - -protected: - QProgressBar *progressBar() const; -}; -#endif - -class QWindowContainer; -class QAccessibleWindowContainer : public QAccessibleWidget -{ -public: - QAccessibleWindowContainer(QWidget *w); - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int i) const Q_DECL_OVERRIDE; - -private: - QWindowContainer *container() const; -}; - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // SIMPLEWIDGETS_H diff --git a/src/plugins/accessible/widgets/widgets.json b/src/plugins/accessible/widgets/widgets.json deleted file mode 100644 index 9ebcc89d35..0000000000 --- a/src/plugins/accessible/widgets/widgets.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "Keys": [ - "QLineEdit", - "QComboBox", - "QAbstractSpinBox", - "QSpinBox", - "QDoubleSpinBox", - "QScrollBar", - "QSlider", - "QAbstractSlider", - "QToolButton", - "QCheckBox", - "QRadioButton", - "QPushButton", - "QAbstractButton", - "QDialog", - "QMessageBox", - "QMainWindow", - "QLabel", - "QLCDNumber", - "QGroupBox", - "QStatusBar", - "QProgressBar", - "QPlainTextEdit", - "QMenuBar", - "QMenu", - "QTabBar", - "QToolBar", - "QSizeGrip", - "QListView", - "QTreeView", - "QTableView", - "QWidget", - "QSplitter", - "QSplitterHandle", - "QTextEdit", - "QTipLabel", - "QFrame", - "QStackedWidget", - "QToolBox", - "QMdiArea", - "QMdiSubWindow", - "QDialogButtonBox", - "QDial", - "QRubberBand", - "QTextBrowser", - "QAbstractScrollArea", - "QScrollArea", - "QCalendarWidget", - "QDockWidget", - "QDesktopScreenWidget", - "QWindowContainer" - ] -} diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro deleted file mode 100644 index aff60d9781..0000000000 --- a/src/plugins/accessible/widgets/widgets.pro +++ /dev/null @@ -1,26 +0,0 @@ -TARGET = qtaccessiblewidgets - -PLUGIN_TYPE = accessible -PLUGIN_CLASS_NAME = AccessibleFactory -load(qt_plugin) - -QT += core-private gui-private widgets-private - -QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)" - -SOURCES += main.cpp \ - simplewidgets.cpp \ - rangecontrols.cpp \ - complexwidgets.cpp \ - qaccessiblewidgets.cpp \ - qaccessiblemenu.cpp \ - itemviews.cpp - -HEADERS += qaccessiblewidgets.h \ - simplewidgets.h \ - rangecontrols.h \ - complexwidgets.h \ - qaccessiblemenu.h \ - itemviews.h - - diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 942db329ca..d1cbff59c1 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -3,6 +3,5 @@ TEMPLATE = subdirs SUBDIRS *= sqldrivers !winrt:qtHaveModule(network): SUBDIRS += bearer qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic -qtHaveModule(widgets): SUBDIRS += accessible !winrt:!wince*:qtHaveModule(widgets):SUBDIRS += printsupport diff --git a/src/widgets/accessible/accessible.pri b/src/widgets/accessible/accessible.pri index 9fb2f18950..bcdfbd639c 100644 --- a/src/widgets/accessible/accessible.pri +++ b/src/widgets/accessible/accessible.pri @@ -1,6 +1,23 @@ # Qt accessibility module contains(QT_CONFIG, accessibility) { - HEADERS += accessible/qaccessiblewidget.h - SOURCES += accessible/qaccessiblewidget.cpp + HEADERS += \ + accessible/qaccessiblewidget.h \ + accessible/qaccessiblewidgetfactory_p.h \ + accessible/complexwidgets.h \ + accessible/itemviews.h \ + accessible/qaccessiblemenu.h \ + accessible/qaccessiblewidgets.h \ + accessible/rangecontrols.h \ + accessible/simplewidgets.h + + SOURCES += \ + accessible/qaccessiblewidget.cpp \ + accessible/qaccessiblewidgetfactory.cpp \ + accessible/complexwidgets.cpp \ + accessible/itemviews.cpp \ + accessible/qaccessiblemenu.cpp \ + accessible/qaccessiblewidgets.cpp \ + accessible/rangecontrols.cpp \ + accessible/simplewidgets.cpp } diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp new file mode 100644 index 0000000000..5d76ecafbc --- /dev/null +++ b/src/widgets/accessible/complexwidgets.cpp @@ -0,0 +1,459 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "complexwidgets.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_ACCESSIBILITY + +QT_BEGIN_NAMESPACE + +QString qt_accStripAmp(const QString &text); + +#ifndef QT_NO_TABBAR +/*! + \class QAccessibleTabBar + \brief The QAccessibleTabBar class implements the QAccessibleInterface for tab bars. + \internal + + \ingroup accessibility +*/ + +class QAccessibleTabButton: public QAccessibleInterface, public QAccessibleActionInterface +{ +public: + QAccessibleTabButton(QTabBar *parent, int index) + : m_parent(parent), m_index(index) + {} + + void *interface_cast(QAccessible::InterfaceType t) { + if (t == QAccessible::ActionInterface) { + return static_cast(this); + } + return 0; + } + + QObject *object() const { return 0; } + QAccessible::Role role() const { return QAccessible::PageTab; } + QAccessible::State state() const { + QAccessibleInterface *parentInterface = parent(); + QAccessible::State state = parentInterface->state(); + return state; + } + QRect rect() const { + if (!isValid()) + return QRect(); + + QPoint tp = m_parent->mapToGlobal(QPoint(0,0)); + QRect rec = m_parent->tabRect(m_index); + rec = QRect(tp.x() + rec.x(), tp.y() + rec.y(), rec.width(), rec.height()); + return rec; + } + + bool isValid() const { return true; }// (!m_parent.isNull()) && m_parent->count() > m_index; } + + QAccessibleInterface *childAt(int, int) const { return 0; } + int childCount() const { return 0; } + int indexOfChild(const QAccessibleInterface *) const { return -1; } + + QString text(QAccessible::Text) const { return qt_accStripAmp(m_parent->tabText(m_index)); } + void setText(QAccessible::Text, const QString &) {} + + QAccessibleInterface *parent() const { + return QAccessible::queryAccessibleInterface(m_parent); + } + QAccessibleInterface *child(int) const { return 0; } + // action interface + QStringList actionNames() const + { + return QStringList(pressAction()); + } + + void doAction(const QString &actionName) + { + if (actionName == pressAction()) + m_parent->setCurrentIndex(m_index); + } + + QStringList keyBindingsForAction(const QString &) const + { + return QStringList(); + } + + int index() const { return m_index; } + +private: + QPointer m_parent; + int m_index; + +}; + +/*! + Constructs a QAccessibleTabBar object for \a w. +*/ +QAccessibleTabBar::QAccessibleTabBar(QWidget *w) +: QAccessibleWidget(w, QAccessible::PageTabList) +{ + Q_ASSERT(tabBar()); +} + +QAccessibleTabBar::~QAccessibleTabBar() +{ + foreach (QAccessible::Id id, m_childInterfaces.values()) + QAccessible::deleteAccessibleInterface(id); +} + +/*! Returns the QTabBar. */ +QTabBar *QAccessibleTabBar::tabBar() const +{ + return qobject_cast(object()); +} + +QAccessibleInterface* QAccessibleTabBar::child(int index) const +{ + if (QAccessible::Id id = m_childInterfaces.value(index)) + return QAccessible::accessibleInterface(id); + + // first the tabs, then 2 buttons + if (index < tabBar()->count()) { + QAccessibleTabButton *button = new QAccessibleTabButton(tabBar(), index); + QAccessible::registerAccessibleInterface(button); + m_childInterfaces.insert(index, QAccessible::uniqueId(button)); + return button; + } else if (index >= tabBar()->count()) { + // left button + if (index - tabBar()->count() == 0) { + return QAccessible::queryAccessibleInterface(tabBar()->d_func()->leftB); + } + // right button + if (index - tabBar()->count() == 1) { + return QAccessible::queryAccessibleInterface(tabBar()->d_func()->rightB); + } + } + return 0; +} + +int QAccessibleTabBar::indexOfChild(const QAccessibleInterface *child) const +{ + if (child->object() && child->object() == tabBar()->d_func()->leftB) + return tabBar()->count(); + if (child->object() && child->object() == tabBar()->d_func()->rightB) + return tabBar()->count() + 1; + if (child->role() == QAccessible::PageTab) { + QAccessibleInterface *parent = child->parent(); + if (parent == this) { + const QAccessibleTabButton *tabButton = static_cast(child); + return tabButton->index(); + } + } + return -1; +} + +int QAccessibleTabBar::childCount() const +{ + // tabs + scroll buttons + return tabBar()->count() + 2; +} + +QString QAccessibleTabBar::text(QAccessible::Text t) const +{ + if (t == QAccessible::Name) { + return qt_accStripAmp(tabBar()->tabText(tabBar()->currentIndex())); + } + return QString(); +} + +#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 +*/ + +/*! + Constructs a QAccessibleComboBox object for \a w. +*/ +QAccessibleComboBox::QAccessibleComboBox(QWidget *w) +: QAccessibleWidget(w, QAccessible::ComboBox) +{ + Q_ASSERT(comboBox()); +} + +/*! + Returns the combobox. +*/ +QComboBox *QAccessibleComboBox::comboBox() const +{ + return qobject_cast(object()); +} + +QAccessibleInterface *QAccessibleComboBox::child(int index) const +{ + if (index == 0) { + QAbstractItemView *view = comboBox()->view(); + //QWidget *parent = view ? view->parentWidget() : 0; + return QAccessible::queryAccessibleInterface(view); + } else if (index == 1 && comboBox()->isEditable()) { + return QAccessible::queryAccessibleInterface(comboBox()->lineEdit()); + } + return 0; +} + +int QAccessibleComboBox::childCount() const +{ + // list and text edit + return comboBox()->isEditable() ? 2 : 1; +} + +QAccessibleInterface *QAccessibleComboBox::childAt(int x, int y) const +{ + if (comboBox()->isEditable() && comboBox()->lineEdit()->rect().contains(x, y)) + return child(1); + return 0; +} + +int QAccessibleComboBox::indexOfChild(const QAccessibleInterface *child) const +{ + if (comboBox()->view() == child->object()) + return 0; + if (comboBox()->isEditable() && comboBox()->lineEdit() == child->object()) + return 1; + return -1; +} + +/*! \reimp */ +QString QAccessibleComboBox::text(QAccessible::Text t) const +{ + QString str; + + switch (t) { + case QAccessible::Name: +#ifndef Q_OS_UNIX // on Linux we use relations for this, name is text (fall through to Value) + str = QAccessibleWidget::text(t); + break; +#endif + case QAccessible::Value: + if (comboBox()->isEditable()) + str = comboBox()->lineEdit()->text(); + else + str = comboBox()->currentText(); + break; +#ifndef QT_NO_SHORTCUT + case QAccessible::Accelerator: + str = QKeySequence(Qt::Key_Down).toString(QKeySequence::NativeText); + break; +#endif + default: + break; + } + if (str.isEmpty()) + str = QAccessibleWidget::text(t); + return str; +} + +QStringList QAccessibleComboBox::actionNames() const +{ + return QStringList(showMenuAction()); +} + +QString QAccessibleComboBox::localizedActionDescription(const QString &actionName) const +{ + if (actionName == showMenuAction()) + return QComboBox::tr("Open the combo box selection popup"); + return QString(); +} + +void QAccessibleComboBox::doAction(const QString &actionName) +{ + if (actionName == showMenuAction()) { + if (comboBox()->view()->isVisible()) { + comboBox()->hidePopup(); + } else { + comboBox()->showPopup(); + } + } +} + +QStringList QAccessibleComboBox::keyBindingsForAction(const QString &/*actionName*/) const +{ + return QStringList(); +} + +#endif // QT_NO_COMBOBOX + +#ifndef QT_NO_SCROLLAREA +// ======================= QAccessibleAbstractScrollArea ======================= +QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Client) +{ + Q_ASSERT(qobject_cast(widget)); +} + +QAccessibleInterface *QAccessibleAbstractScrollArea::child(int index) const +{ + return QAccessible::queryAccessibleInterface(accessibleChildren().at(index)); +} + +int QAccessibleAbstractScrollArea::childCount() const +{ + return accessibleChildren().count(); +} + +int QAccessibleAbstractScrollArea::indexOfChild(const QAccessibleInterface *child) const +{ + if (!child || !child->object()) + return -1; + return accessibleChildren().indexOf(qobject_cast(child->object())); +} + +bool QAccessibleAbstractScrollArea::isValid() const +{ + return (QAccessibleWidget::isValid() && abstractScrollArea() && abstractScrollArea()->viewport()); +} + +QAccessibleInterface *QAccessibleAbstractScrollArea::childAt(int x, int y) const +{ + if (!abstractScrollArea()->isVisible()) + return 0; + + for (int i = 0; i < childCount(); ++i) { + QPoint wpos = accessibleChildren().at(i)->mapToGlobal(QPoint(0, 0)); + QRect rect = QRect(wpos, accessibleChildren().at(i)->size()); + if (rect.contains(x, y)) + return child(i); + } + return 0; +} + +QAbstractScrollArea *QAccessibleAbstractScrollArea::abstractScrollArea() const +{ + return static_cast(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(widget)); +} +#endif // QT_NO_SCROLLAREA + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/widgets/accessible/complexwidgets.h b/src/widgets/accessible/complexwidgets.h new file mode 100644 index 0000000000..00186282f3 --- /dev/null +++ b/src/widgets/accessible/complexwidgets.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COMPLEXWIDGETS_H +#define COMPLEXWIDGETS_H + +#include +#include +#include + +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 QAccessibleWidget +{ +public: + explicit QAccessibleAbstractScrollArea(QWidget *widget); + + enum AbstractScrollAreaElement { + Self = 0, + Viewport, + HorizontalContainer, + VerticalContainer, + CornerWidget, + Undefined + }; + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + +//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_TABBAR +class QAccessibleTabBar : public QAccessibleWidget +{ +public: + explicit QAccessibleTabBar(QWidget *w); + ~QAccessibleTabBar(); + + int childCount() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + +protected: + QTabBar *tabBar() const; + mutable QHash m_childInterfaces; +}; +#endif // QT_NO_TABBAR + +#ifndef QT_NO_COMBOBOX +class QAccessibleComboBox : public QAccessibleWidget +{ +public: + explicit QAccessibleComboBox(QWidget *w); + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + // QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + QString localizedActionDescription(const QString &actionName) const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + +protected: + QComboBox *comboBox() const; +}; +#endif // QT_NO_COMBOBOX + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // COMPLEXWIDGETS_H diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp new file mode 100644 index 0000000000..81736fc1c6 --- /dev/null +++ b/src/widgets/accessible/itemviews.cpp @@ -0,0 +1,1222 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "itemviews.h" + +#include +#include +#include +#include +#include + +#ifndef QT_NO_ACCESSIBILITY + +QT_BEGIN_NAMESPACE + +QString qt_accStripAmp(const QString &text); + +#ifndef QT_NO_ITEMVIEWS +/* +Implementation of the IAccessible2 table2 interface. Much simpler than +the other table interfaces since there is only the main table and cells: + +TABLE/LIST/TREE + |- HEADER CELL + |- CELL + |- CELL + ... +*/ + + +QAbstractItemView *QAccessibleTable::view() const +{ + return qobject_cast(object()); +} + +int QAccessibleTable::logicalIndex(const QModelIndex &index) const +{ + if (!view()->model() || !index.isValid()) + return -1; + int vHeader = verticalHeader() ? 1 : 0; + int hHeader = horizontalHeader() ? 1 : 0; + return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader); +} + +QAccessibleTable::QAccessibleTable(QWidget *w) + : QAccessibleObject(w) +{ + Q_ASSERT(view()); + + if (qobject_cast(view())) { + m_role = QAccessible::Table; + } else if (qobject_cast(view())) { + m_role = QAccessible::Tree; + } else if (qobject_cast(view())) { + m_role = QAccessible::List; + } else { + // is this our best guess? + m_role = QAccessible::Table; + } +} + +bool QAccessibleTable::isValid() const +{ + return (view() && !qobject_cast(view())->d_func()->data.in_destructor); +} + +QAccessibleTable::~QAccessibleTable() +{ + Q_FOREACH (QAccessible::Id id, childToId.values()) + QAccessible::deleteAccessibleInterface(id); +} + +QHeaderView *QAccessibleTable::horizontalHeader() const +{ + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast(view())) { + header = tv->horizontalHeader(); +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast(view())) { + header = tv->header(); +#endif + } + return header; +} + +QHeaderView *QAccessibleTable::verticalHeader() const +{ + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast(view())) { + header = tv->verticalHeader(); +#endif + } + return header; +} + +QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const +{ + if (!view()->model()) + return 0; + Q_ASSERT(role() != QAccessible::Tree); + QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); + if (!index.isValid()) { + qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view(); + return 0; + } + return child(logicalIndex(index)); +} + +QAccessibleInterface *QAccessibleTable::caption() const +{ + return 0; +} + +QString QAccessibleTable::columnDescription(int column) const +{ + if (!view()->model()) + return QString(); + return view()->model()->headerData(column, Qt::Horizontal).toString(); +} + +int QAccessibleTable::columnCount() const +{ + if (!view()->model()) + return 0; + return view()->model()->columnCount(); +} + +int QAccessibleTable::rowCount() const +{ + if (!view()->model()) + return 0; + return view()->model()->rowCount(); +} + +int QAccessibleTable::selectedCellCount() const +{ + if (!view()->selectionModel()) + return 0; + return view()->selectionModel()->selectedIndexes().count(); +} + +int QAccessibleTable::selectedColumnCount() const +{ + if (!view()->selectionModel()) + return 0; + return view()->selectionModel()->selectedColumns().count(); +} + +int QAccessibleTable::selectedRowCount() const +{ + if (!view()->selectionModel()) + return 0; + return view()->selectionModel()->selectedRows().count(); +} + +QString QAccessibleTable::rowDescription(int row) const +{ + if (!view()->model()) + return QString(); + return view()->model()->headerData(row, Qt::Vertical).toString(); +} + +QList QAccessibleTable::selectedCells() const +{ + QList cells; + if (!view()->selectionModel()) + return cells; + Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes()) + cells.append(child(logicalIndex(index))); + return cells; +} + +QList QAccessibleTable::selectedColumns() const +{ + if (!view()->selectionModel()) + return QList(); + QList columns; + Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) { + columns.append(index.column()); + } + return columns; +} + +QList QAccessibleTable::selectedRows() const +{ + if (!view()->selectionModel()) + return QList(); + QList rows; + Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) { + rows.append(index.row()); + } + return rows; +} + +QAccessibleInterface *QAccessibleTable::summary() const +{ + return 0; +} + +bool QAccessibleTable::isColumnSelected(int column) const +{ + if (!view()->selectionModel()) + return false; + return view()->selectionModel()->isColumnSelected(column, QModelIndex()); +} + +bool QAccessibleTable::isRowSelected(int row) const +{ + if (!view()->selectionModel()) + return false; + return view()->selectionModel()->isRowSelected(row, QModelIndex()); +} + +bool QAccessibleTable::selectRow(int row) +{ + if (!view()->model() || !view()->selectionModel()) + return false; + QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); + + if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) + return false; + + switch (view()->selectionMode()) { + case QAbstractItemView::NoSelection: + return false; + case QAbstractItemView::SingleSelection: + if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 ) + return false; + view()->clearSelection(); + break; + case QAbstractItemView::ContiguousSelection: + if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) + && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) + view()->clearSelection(); + break; + default: + break; + } + + view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + return true; +} + +bool QAccessibleTable::selectColumn(int column) +{ + if (!view()->model() || !view()->selectionModel()) + return false; + QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); + + if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectRows) + return false; + + switch (view()->selectionMode()) { + case QAbstractItemView::NoSelection: + return false; + case QAbstractItemView::SingleSelection: + if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) + return false; + case QAbstractItemView::ContiguousSelection: + if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) + && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) + view()->clearSelection(); + break; + default: + break; + } + + view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Columns); + return true; +} + +bool QAccessibleTable::unselectRow(int row) +{ + if (!view()->model() || !view()->selectionModel()) + return false; + + QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); + if (!index.isValid()) + return false; + + QItemSelection selection(index, index); + + switch (view()->selectionMode()) { + case QAbstractItemView::SingleSelection: + //In SingleSelection and ContiguousSelection once an item + //is selected, there's no way for the user to unselect all items + if (selectedRowCount() == 1) + return false; + break; + case QAbstractItemView::ContiguousSelection: + if (selectedRowCount() == 1) + return false; + + if ((!row || view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) + && view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { + //If there are rows selected both up the current row and down the current rown, + //the ones which are down the current row will be deselected + selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex())); + } + default: + break; + } + + view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Rows); + return true; +} + +bool QAccessibleTable::unselectColumn(int column) +{ + if (!view()->model() || !view()->selectionModel()) + return false; + + QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); + if (!index.isValid()) + return false; + + QItemSelection selection(index, index); + + switch (view()->selectionMode()) { + case QAbstractItemView::SingleSelection: + //In SingleSelection and ContiguousSelection once an item + //is selected, there's no way for the user to unselect all items + if (selectedColumnCount() == 1) + return false; + break; + case QAbstractItemView::ContiguousSelection: + if (selectedColumnCount() == 1) + return false; + + if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) + && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { + //If there are columns selected both at the left of the current row and at the right + //of the current rown, the ones which are at the right will be deselected + selection = QItemSelection(index, view()->model()->index(0, columnCount() - 1, view()->rootIndex())); + } + default: + break; + } + + view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Columns); + return true; +} + +QAccessible::Role QAccessibleTable::role() const +{ + return m_role; +} + +QAccessible::State QAccessibleTable::state() const +{ + return QAccessible::State(); +} + +QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const +{ + QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); + QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); + // FIXME: if indexPosition < 0 in one coordinate, return header + + QModelIndex index = view()->indexAt(indexPosition); + if (index.isValid()) { + return child(logicalIndex(index)); + } + return 0; +} + +int QAccessibleTable::childCount() const +{ + if (!view()->model()) + return 0; + int vHeader = verticalHeader() ? 1 : 0; + int hHeader = horizontalHeader() ? 1 : 0; + return (view()->model()->rowCount()+hHeader) * (view()->model()->columnCount()+vHeader); +} + +int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const +{ + if (!view()->model()) + return -1; + QAccessibleInterface *parent = iface->parent(); + if (parent->object() != view()) + return -1; + + Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class + if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { + const QAccessibleTableCell* cell = static_cast(iface); + return logicalIndex(cell->m_index); + } else if (iface->role() == QAccessible::ColumnHeader){ + const QAccessibleTableHeaderCell* cell = static_cast(iface); + return cell->index + (verticalHeader() ? 1 : 0); + } else if (iface->role() == QAccessible::RowHeader){ + const QAccessibleTableHeaderCell* cell = static_cast(iface); + return (cell->index + 1) * (view()->model()->columnCount() + 1); + } else if (iface->role() == QAccessible::Pane) { + return 0; // corner button + } else { + qWarning() << "WARNING QAccessibleTable::indexOfChild Fix my children..." + << iface->role() << iface->text(QAccessible::Name); + } + // FIXME: we are in denial of our children. this should stop. + return -1; +} + +QString QAccessibleTable::text(QAccessible::Text t) const +{ + if (t == QAccessible::Description) + return view()->accessibleDescription(); + return view()->accessibleName(); +} + +QRect QAccessibleTable::rect() const +{ + if (!view()->isVisible()) + return QRect(); + QPoint pos = view()->mapToGlobal(QPoint(0, 0)); + return QRect(pos.x(), pos.y(), view()->width(), view()->height()); +} + +QAccessibleInterface *QAccessibleTable::parent() const +{ + if (view() && view()->parent()) { + if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) { + return QAccessible::queryAccessibleInterface(view()->parent()->parent()); + } + return QAccessible::queryAccessibleInterface(view()->parent()); + } + return 0; +} + +QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const +{ + if (!view()->model()) + return 0; + + if (childToId.contains(logicalIndex)) { + QAccessible::Id id = childToId.value(logicalIndex); + return QAccessible::accessibleInterface(id); + } + + int vHeader = verticalHeader() ? 1 : 0; + int hHeader = horizontalHeader() ? 1 : 0; + + int columns = view()->model()->columnCount() + vHeader; + + int row = logicalIndex / columns; + int column = logicalIndex % columns; + + QAccessibleInterface *iface = 0; + + if (vHeader) { + if (column == 0) { + if (hHeader && row == 0) { + iface = new QAccessibleTableCornerButton(view()); + } else { + iface = new QAccessibleTableHeaderCell(view(), row - hHeader, Qt::Vertical); + } + } + --column; + } + if (!iface && hHeader) { + if (row == 0) { + iface = new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal); + } + --row; + } + + if (!iface) { + QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); + if (!index.isValid()) { + qWarning() << "QAccessibleTable::child: Invalid index at: " << row << column; + return 0; + } + iface = new QAccessibleTableCell(view(), index, cellRole()); + } + + QAccessible::registerAccessibleInterface(iface); + childToId.insert(logicalIndex, QAccessible::uniqueId(iface)); + return iface; +} + +void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::TableInterface) + return static_cast(this); + return 0; +} + +void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event) +{ + // if there is no cache yet, we don't update anything + if (childToId.isEmpty()) + return; + + switch (event->modelChangeType()) { + case QAccessibleTableModelChangeEvent::ModelReset: + Q_FOREACH (QAccessible::Id id, childToId.values()) + QAccessible::deleteAccessibleInterface(id); + childToId.clear(); + break; + + // rows are inserted: move every row after that + case QAccessibleTableModelChangeEvent::RowsInserted: + case QAccessibleTableModelChangeEvent::ColumnsInserted: { + int newRows = event->lastRow() - event->firstRow() + 1; + int newColumns = event->lastColumn() - event->firstColumn() + 1; + + ChildCache newCache; + ChildCache::ConstIterator iter = childToId.constBegin(); + + while (iter != childToId.constEnd()) { + QAccessible::Id id = iter.value(); + QAccessibleInterface *iface = QAccessible::accessibleInterface(id); + Q_ASSERT(iface); + if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { + Q_ASSERT(iface->tableCellInterface()); + QAccessibleTableCell *cell = static_cast(iface->tableCellInterface()); + if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted + && cell->m_index.row() >= event->firstRow()) { + int newRow = cell->m_index.row() + newRows; + cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column()); + } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted + && cell->m_index.column() >= event->firstColumn()) { + int newColumn = cell->m_index.column() + newColumns; + cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn); + } + } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted + && iface->role() == QAccessible::RowHeader) { + QAccessibleTableHeaderCell *cell = static_cast(iface); + if (cell->index >= event->firstRow()) { + cell->index += newRows; + } + } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted + && iface->role() == QAccessible::ColumnHeader) { + QAccessibleTableHeaderCell *cell = static_cast(iface); + if (cell->index >= event->firstColumn()) { + cell->index += newColumns; + } + } + if (indexOfChild(iface) >= 0) { + newCache.insert(indexOfChild(iface), id); + } else { + // ### This should really not happen, + // but it might if the view has a root index set. + // This needs to be fixed. + QAccessible::deleteAccessibleInterface(id); + } + ++iter; + } + childToId = newCache; + break; + } + + case QAccessibleTableModelChangeEvent::ColumnsRemoved: + case QAccessibleTableModelChangeEvent::RowsRemoved: { + int deletedColumns = event->lastColumn() - event->firstColumn() + 1; + int deletedRows = event->lastRow() - event->firstRow() + 1; + ChildCache newCache; + ChildCache::ConstIterator iter = childToId.constBegin(); + while (iter != childToId.constEnd()) { + QAccessible::Id id = iter.value(); + QAccessibleInterface *iface = QAccessible::accessibleInterface(id); + Q_ASSERT(iface); + if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { + Q_ASSERT(iface->tableCellInterface()); + QAccessibleTableCell *cell = static_cast(iface->tableCellInterface()); + if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved) { + if (cell->m_index.row() < event->firstRow()) { + newCache.insert(indexOfChild(cell), id); + } else if (cell->m_index.row() > event->lastRow()) { + int newRow = cell->m_index.row() - deletedRows; + cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column()); + newCache.insert(indexOfChild(cell), id); + } else { + QAccessible::deleteAccessibleInterface(id); + } + } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved) { + if (cell->m_index.column() < event->firstColumn()) { + newCache.insert(indexOfChild(cell), id); + } else if (cell->m_index.column() > event->lastColumn()) { + int newColumn = cell->m_index.column() - deletedColumns; + cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn); + newCache.insert(indexOfChild(cell), id); + } else { + QAccessible::deleteAccessibleInterface(id); + } + } + } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved + && iface->role() == QAccessible::RowHeader) { + QAccessibleTableHeaderCell *cell = static_cast(iface); + if (cell->index < event->firstRow()) { + newCache.insert(indexOfChild(cell), id); + } else if (cell->index > event->lastRow()) { + cell->index -= deletedRows; + newCache.insert(indexOfChild(cell), id); + } else { + QAccessible::deleteAccessibleInterface(id); + } + } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved + && iface->role() == QAccessible::ColumnHeader) { + QAccessibleTableHeaderCell *cell = static_cast(iface); + if (cell->index < event->firstColumn()) { + newCache.insert(indexOfChild(cell), id); + } else if (cell->index > event->lastColumn()) { + cell->index -= deletedColumns; + newCache.insert(indexOfChild(cell), id); + } else { + QAccessible::deleteAccessibleInterface(id); + } + } + ++iter; + } + childToId = newCache; + break; + } + + case QAccessibleTableModelChangeEvent::DataChanged: + // nothing to do in this case + break; + } +} + +// TREE VIEW + +QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const +{ + if (!isValid() || !view()->model()) + return QModelIndex(); + + const QTreeView *treeView = qobject_cast(view()); + if ((row < 0) || (column < 0) || (treeView->d_func()->viewItems.count() <= row)) { + qWarning() << "QAccessibleTree::indexFromLogical: invalid index: " << row << column << " for " << treeView; + return QModelIndex(); + } + QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index; + + if (modelIndex.isValid() && column > 0) { + modelIndex = view()->model()->index(modelIndex.row(), column, modelIndex.parent()); + } + return modelIndex; +} + +QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const +{ + if (!view()->model()) + return 0; + QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); + QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); + + QModelIndex index = view()->indexAt(indexPosition); + if (!index.isValid()) + return 0; + + const QTreeView *treeView = qobject_cast(view()); + int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0); + int column = index.column(); + + int i = row * view()->model()->columnCount() + column; + return child(i); +} + +int QAccessibleTree::childCount() const +{ + const QTreeView *treeView = qobject_cast(view()); + Q_ASSERT(treeView); + if (!view()->model()) + return 0; + + int hHeader = horizontalHeader() ? 1 : 0; + return (treeView->d_func()->viewItems.count() + hHeader)* view()->model()->columnCount(); +} + + +QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const +{ + if (logicalIndex < 0 || !view()->model() || !view()->model()->columnCount()) + return 0; + + QAccessibleInterface *iface = 0; + int index = logicalIndex; + + if (horizontalHeader()) { + if (index < view()->model()->columnCount()) { + iface = new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal); + } else { + index -= view()->model()->columnCount(); + } + } + + if (!iface) { + int row = index / view()->model()->columnCount(); + int column = index % view()->model()->columnCount(); + QModelIndex modelIndex = indexFromLogical(row, column); + if (!modelIndex.isValid()) + return 0; + iface = new QAccessibleTableCell(view(), modelIndex, cellRole()); + } + QAccessible::registerAccessibleInterface(iface); + // ### FIXME: get interfaces from the cache instead of re-creating them + return iface; +} + +int QAccessibleTree::rowCount() const +{ + const QTreeView *treeView = qobject_cast(view()); + Q_ASSERT(treeView); + return treeView->d_func()->viewItems.count(); +} + +int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const +{ + if (!view()->model()) + return -1; + QAccessibleInterface *parent = iface->parent(); + if (parent->object() != view()) + return -1; + + if (iface->role() == QAccessible::TreeItem) { + const QAccessibleTableCell* cell = static_cast(iface); + const QTreeView *treeView = qobject_cast(view()); + Q_ASSERT(treeView); + int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0); + int column = cell->m_index.column(); + + int index = row * view()->model()->columnCount() + column; + return index; + } else if (iface->role() == QAccessible::ColumnHeader){ + const QAccessibleTableHeaderCell* cell = static_cast(iface); + return cell->index; + } else { + qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child" + << iface->role() << iface->text(QAccessible::Name); + } + // FIXME: add scrollbars and don't just ignore them + return -1; +} + +QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const +{ + QModelIndex index = indexFromLogical(row, column); + if (!index.isValid()) { + qWarning() << "Requested invalid tree cell: " << row << column; + return 0; + } + const QTreeView *treeView = qobject_cast(view()); + Q_ASSERT(treeView); + int logicalIndex = treeView->d_func()->accessibleTable2Index(index); + + return child(logicalIndex); // FIXME ### new QAccessibleTableCell(view(), index, cellRole()); +} + +QString QAccessibleTree::rowDescription(int) const +{ + return QString(); // no headers for rows in trees +} + +bool QAccessibleTree::isRowSelected(int row) const +{ + if (!view()->selectionModel()) + return false; + QModelIndex index = indexFromLogical(row); + return view()->selectionModel()->isRowSelected(index.row(), index.parent()); +} + +bool QAccessibleTree::selectRow(int row) +{ + if (!view()->selectionModel()) + return false; + QModelIndex index = indexFromLogical(row); + + if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) + return false; + + switch (view()->selectionMode()) { + case QAbstractItemView::NoSelection: + return false; + case QAbstractItemView::SingleSelection: + if ((view()->selectionBehavior() != QAbstractItemView::SelectRows) && (columnCount() > 1)) + return false; + view()->clearSelection(); + break; + case QAbstractItemView::ContiguousSelection: + if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) + && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) + view()->clearSelection(); + break; + default: + break; + } + + view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + return true; +} + +// TABLE CELL + +QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_) + : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_) +{ + if (!index_.isValid()) + qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_; +} + +void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::TableCellInterface) + return static_cast(this); + if (t == QAccessible::ActionInterface) + return static_cast(this); + return 0; +} + +int QAccessibleTableCell::columnExtent() const { return 1; } +int QAccessibleTableCell::rowExtent() const { return 1; } + +QList QAccessibleTableCell::rowHeaderCells() const +{ + QList headerCell; + if (verticalHeader()) { + // FIXME + headerCell.append(new QAccessibleTableHeaderCell(view, m_index.row(), Qt::Vertical)); + } + return headerCell; +} + +QList QAccessibleTableCell::columnHeaderCells() const +{ + QList headerCell; + if (horizontalHeader()) { + // FIXME + headerCell.append(new QAccessibleTableHeaderCell(view, m_index.column(), Qt::Horizontal)); + } + return headerCell; +} + +QHeaderView *QAccessibleTableCell::horizontalHeader() const +{ + QHeaderView *header = 0; + + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast(view)) { + header = tv->horizontalHeader(); +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast(view)) { + header = tv->header(); +#endif + } + + return header; +} + +QHeaderView *QAccessibleTableCell::verticalHeader() const +{ + QHeaderView *header = 0; +#ifndef QT_NO_TABLEVIEW + if (const QTableView *tv = qobject_cast(view)) + header = tv->verticalHeader(); +#endif + return header; +} + +int QAccessibleTableCell::columnIndex() const +{ + return m_index.column(); +} + +int QAccessibleTableCell::rowIndex() const +{ + if (role() == QAccessible::TreeItem) { + const QTreeView *treeView = qobject_cast(view); + Q_ASSERT(treeView); + int row = treeView->d_func()->viewIndex(m_index); + return row; + } + return m_index.row(); +} + +bool QAccessibleTableCell::isSelected() const +{ + return view->selectionModel()->isSelected(m_index); +} + +QStringList QAccessibleTableCell::actionNames() const +{ + QStringList names; + names << toggleAction(); + return names; +} + +void QAccessibleTableCell::doAction(const QString& actionName) +{ + if (actionName == toggleAction()) { + if (isSelected()) + unselectCell(); + else + selectCell(); + } +} + +QStringList QAccessibleTableCell::keyBindingsForAction(const QString &) const +{ + return QStringList(); +} + + +void QAccessibleTableCell::selectCell() +{ + QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); + if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection)) + return; + Q_ASSERT(table()); + QAccessibleTableInterface *cellTable = table()->tableInterface(); + + switch (view->selectionBehavior()) { + case QAbstractItemView::SelectItems: + break; + case QAbstractItemView::SelectColumns: + if (cellTable) + cellTable->selectColumn(m_index.column()); + return; + case QAbstractItemView::SelectRows: + if (cellTable) + cellTable->selectRow(m_index.row()); + return; + } + + if (selectionMode == QAbstractItemView::SingleSelection) { + view->clearSelection(); + } + + view->selectionModel()->select(m_index, QItemSelectionModel::Select); +} + +void QAccessibleTableCell::unselectCell() +{ + + QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); + if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection)) + return; + + QAccessibleTableInterface *cellTable = table()->tableInterface(); + + switch (view->selectionBehavior()) { + case QAbstractItemView::SelectItems: + break; + case QAbstractItemView::SelectColumns: + if (cellTable) + cellTable->unselectColumn(m_index.column()); + return; + case QAbstractItemView::SelectRows: + if (cellTable) + cellTable->unselectRow(m_index.row()); + return; + } + + //If the mode is not MultiSelection or ExtendedSelection and only + //one cell is selected it cannot be unselected by the user + if ((selectionMode != QAbstractItemView::MultiSelection) + && (selectionMode != QAbstractItemView::ExtendedSelection) + && (view->selectionModel()->selectedIndexes().count() <= 1)) + return; + + view->selectionModel()->select(m_index, QItemSelectionModel::Deselect); +} + +QAccessibleInterface *QAccessibleTableCell::table() const +{ + return QAccessible::queryAccessibleInterface(view); +} + +QAccessible::Role QAccessibleTableCell::role() const +{ + return m_role; +} + +QAccessible::State QAccessibleTableCell::state() const +{ + QAccessible::State st; + QRect globalRect = view->rect(); + globalRect.translate(view->mapToGlobal(QPoint(0,0))); + if (!globalRect.intersects(rect())) + st.invisible = true; + + if (view->selectionModel()->isSelected(m_index)) + st.selected = true; + if (view->selectionModel()->currentIndex() == m_index) + st.focused = true; + if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked) + st.checked = true; + + Qt::ItemFlags flags = m_index.flags(); + if (flags & Qt::ItemIsSelectable) { + st.selectable = true; + st.focusable = true; + if (view->selectionMode() == QAbstractItemView::MultiSelection) + st.multiSelectable = true; + if (view->selectionMode() == QAbstractItemView::ExtendedSelection) + st.extSelectable = true; + } + if (m_role == QAccessible::TreeItem) { + const QTreeView *treeView = qobject_cast(view); + if (treeView->model()->hasChildren(m_index)) + st.expandable = true; + if (treeView->isExpanded(m_index)) + st.expanded = true; + } + return st; +} + + +QRect QAccessibleTableCell::rect() const +{ + QRect r; + r = view->visualRect(m_index); + + if (!r.isNull()) { + r.translate(view->viewport()->mapTo(view, QPoint(0,0))); + r.translate(view->mapToGlobal(QPoint(0, 0))); + } + return r; +} + +QString QAccessibleTableCell::text(QAccessible::Text t) const +{ + QAbstractItemModel *model = view->model(); + QString value; + switch (t) { + case QAccessible::Name: + value = model->data(m_index, Qt::AccessibleTextRole).toString(); + if (value.isEmpty()) + value = model->data(m_index, Qt::DisplayRole).toString(); + break; + case QAccessible::Description: + value = model->data(m_index, Qt::AccessibleDescriptionRole).toString(); + break; + default: + break; + } + return value; +} + +void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text) +{ + if (!(m_index.flags() & Qt::ItemIsEditable)) + return; + view->model()->setData(m_index, text); +} + +bool QAccessibleTableCell::isValid() const +{ + return view && view->model() && m_index.isValid(); +} + +QAccessibleInterface *QAccessibleTableCell::parent() const +{ + return QAccessible::queryAccessibleInterface(view); +} + +QAccessibleInterface *QAccessibleTableCell::child(int) const +{ + return 0; +} + +QAccessibleTableHeaderCell::QAccessibleTableHeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_) + : view(view_), index(index_), orientation(orientation_) +{ + Q_ASSERT(index_ >= 0); +} + +QAccessible::Role QAccessibleTableHeaderCell::role() const +{ + if (orientation == Qt::Horizontal) + return QAccessible::ColumnHeader; + return QAccessible::RowHeader; +} + +QAccessible::State QAccessibleTableHeaderCell::state() const +{ + QAccessible::State s; + if (QHeaderView *h = headerView()) { + s.invisible = !h->testAttribute(Qt::WA_WState_Visible); + s.disabled = !h->isEnabled(); + } + return s; +} + +QRect QAccessibleTableHeaderCell::rect() const +{ + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast(view)) { + if (orientation == Qt::Horizontal) { + header = tv->horizontalHeader(); + } else { + header = tv->verticalHeader(); + } +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast(view)) { + header = tv->header(); +#endif + } + if (!header) + return QRect(); + QPoint zero = header->mapToGlobal(QPoint(0, 0)); + int sectionSize = header->sectionSize(index); + int sectionPos = header->sectionPosition(index); + return orientation == Qt::Horizontal + ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height()) + : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize); +} + +QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const +{ + QAbstractItemModel *model = view->model(); + QString value; + switch (t) { + case QAccessible::Name: + value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString(); + if (value.isEmpty()) + value = model->headerData(index, orientation, Qt::DisplayRole).toString(); + break; + case QAccessible::Description: + value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString(); + break; + default: + break; + } + return value; +} + +void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &) +{ + return; +} + +bool QAccessibleTableHeaderCell::isValid() const +{ + return view && view->model() && (index >= 0) + && ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount())); +} + +QAccessibleInterface *QAccessibleTableHeaderCell::parent() const +{ + return QAccessible::queryAccessibleInterface(view); +} + +QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const +{ + return 0; +} + +QHeaderView *QAccessibleTableHeaderCell::headerView() const +{ + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast(view)) { + if (orientation == Qt::Horizontal) { + header = tv->horizontalHeader(); + } else { + header = tv->verticalHeader(); + } +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast(view)) { + header = tv->header(); +#endif + } + return header; +} + +#endif // QT_NO_ITEMVIEWS + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/widgets/accessible/itemviews.h b/src/widgets/accessible/itemviews.h new file mode 100644 index 0000000000..45a07c5972 --- /dev/null +++ b/src/widgets/accessible/itemviews.h @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ACCESSIBLE_ITEMVIEWS_H +#define ACCESSIBLE_ITEMVIEWS_H + +#include "QtCore/qpointer.h" +#include +#include +#include +#include + + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +#ifndef QT_NO_ITEMVIEWS + +class QAccessibleTableCell; +class QAccessibleTableHeaderCell; + +class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObject +{ +public: + explicit QAccessibleTable(QWidget *w); + bool isValid() const Q_DECL_OVERRIDE; + + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // table interface + virtual QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; + virtual QAccessibleInterface *caption() const Q_DECL_OVERRIDE; + virtual QAccessibleInterface *summary() const Q_DECL_OVERRIDE; + virtual QString columnDescription(int column) const Q_DECL_OVERRIDE; + virtual QString rowDescription(int row) const Q_DECL_OVERRIDE; + virtual int columnCount() const Q_DECL_OVERRIDE; + virtual int rowCount() const Q_DECL_OVERRIDE; + + // selection + virtual int selectedCellCount() const Q_DECL_OVERRIDE; + virtual int selectedColumnCount() const Q_DECL_OVERRIDE; + virtual int selectedRowCount() const Q_DECL_OVERRIDE; + virtual QList selectedCells() const Q_DECL_OVERRIDE; + virtual QList selectedColumns() const Q_DECL_OVERRIDE; + virtual QList selectedRows() const Q_DECL_OVERRIDE; + virtual bool isColumnSelected(int column) const Q_DECL_OVERRIDE; + virtual bool isRowSelected(int row) const Q_DECL_OVERRIDE; + virtual bool selectRow(int row) Q_DECL_OVERRIDE; + virtual bool selectColumn(int column) Q_DECL_OVERRIDE; + virtual bool unselectRow(int row) Q_DECL_OVERRIDE; + virtual bool unselectColumn(int column) Q_DECL_OVERRIDE; + + QAbstractItemView *view() const; + + void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE; + +protected: + inline QAccessible::Role cellRole() const { + switch (m_role) { + case QAccessible::List: + return QAccessible::ListItem; + case QAccessible::Table: + return QAccessible::Cell; + case QAccessible::Tree: + return QAccessible::TreeItem; + default: + Q_ASSERT(0); + } + return QAccessible::NoRole; + } + + QHeaderView *horizontalHeader() const; + QHeaderView *verticalHeader() const; + + // maybe vector + typedef QHash ChildCache; + mutable ChildCache childToId; + + virtual ~QAccessibleTable(); + +private: + // the child index for a model index + inline int logicalIndex(const QModelIndex &index) const; + QAccessible::Role m_role; +}; + +class QAccessibleTree :public QAccessibleTable +{ +public: + explicit QAccessibleTree(QWidget *w) + : QAccessibleTable(w) + {} + + + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; + + int rowCount() const Q_DECL_OVERRIDE; + + // table interface + QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; + QString rowDescription(int row) const Q_DECL_OVERRIDE; + bool isRowSelected(int row) const Q_DECL_OVERRIDE; + bool selectRow(int row) Q_DECL_OVERRIDE; + +private: + QModelIndex indexFromLogical(int row, int column = 0) const; + + inline int logicalIndex(const QModelIndex &index) const; +}; + +class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface +{ +public: + QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + QObject *object() const Q_DECL_OVERRIDE { return 0; } + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + int childCount() const Q_DECL_OVERRIDE { return 0; } + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int) const Q_DECL_OVERRIDE; + + // cell interface + virtual int columnExtent() const Q_DECL_OVERRIDE; + virtual QList columnHeaderCells() const Q_DECL_OVERRIDE; + virtual int columnIndex() const Q_DECL_OVERRIDE; + virtual int rowExtent() const Q_DECL_OVERRIDE; + virtual QList rowHeaderCells() const Q_DECL_OVERRIDE; + virtual int rowIndex() const Q_DECL_OVERRIDE; + virtual bool isSelected() const Q_DECL_OVERRIDE; + virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE; + + //action interface + virtual QStringList actionNames() const Q_DECL_OVERRIDE; + virtual void doAction(const QString &actionName) Q_DECL_OVERRIDE; + virtual QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + +private: + QHeaderView *verticalHeader() const; + QHeaderView *horizontalHeader() const; + QPointer view; + QModelIndex m_index; + QAccessible::Role m_role; + + void selectCell(); + void unselectCell(); + +friend class QAccessibleTable; +friend class QAccessibleTree; +}; + + +class QAccessibleTableHeaderCell: public QAccessibleInterface +{ +public: + // For header cells, pass the header view in addition + QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); + + QObject *object() const Q_DECL_OVERRIDE { return 0; } + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + int childCount() const Q_DECL_OVERRIDE { return 0; } + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +private: + QHeaderView *headerView() const; + + QPointer view; + int index; + Qt::Orientation orientation; + +friend class QAccessibleTable; +friend class QAccessibleTree; +}; + +// This is the corner button on the top left of a table. +// It can be used to select all cells or it is not active at all. +// For now it is ignored. +class QAccessibleTableCornerButton: public QAccessibleInterface +{ +public: + QAccessibleTableCornerButton(QAbstractItemView *view_) + :view(view_) + {} + + QObject *object() const Q_DECL_OVERRIDE { return 0; } + QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::Pane; } + QAccessible::State state() const Q_DECL_OVERRIDE { return QAccessible::State(); } + QRect rect() const Q_DECL_OVERRIDE { return QRect(); } + bool isValid() const Q_DECL_OVERRIDE { return true; } + + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + int childCount() const Q_DECL_OVERRIDE { return 0; } + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } + + QString text(QAccessible::Text) const Q_DECL_OVERRIDE { return QString(); } + void setText(QAccessible::Text, const QString &) Q_DECL_OVERRIDE {} + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE { + return QAccessible::queryAccessibleInterface(view); + } + QAccessibleInterface *child(int) const Q_DECL_OVERRIDE { + return 0; + } + +private: + QPointer view; +}; + + +#endif + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // ACCESSIBLE_ITEMVIEWS_H diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp new file mode 100644 index 0000000000..a6877404eb --- /dev/null +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaccessiblemenu.h" + +#include +#include +#include +#include + +#ifndef QT_NO_ACCESSIBILITY + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_MENU + +QString qt_accStripAmp(const QString &text); +QString qt_accHotKey(const QString &text); + +QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action) +{ + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action); + if (!iface) { + iface = new QAccessibleMenuItem(menu, action); + QAccessible::registerAccessibleInterface(iface); + } + return iface; +} + +QAccessibleMenu::QAccessibleMenu(QWidget *w) +: QAccessibleWidget(w) +{ + Q_ASSERT(menu()); +} + +QMenu *QAccessibleMenu::menu() const +{ + return qobject_cast(object()); +} + +int QAccessibleMenu::childCount() const +{ + return menu()->actions().count(); +} + +QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const +{ + QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y))); + if(act && act->isSeparator()) + act = 0; + return act ? getOrCreateMenu(menu(), act) : 0; +} + +QString QAccessibleMenu::text(QAccessible::Text t) const +{ + QString tx = QAccessibleWidget::text(t); + if (!tx.isEmpty()) + return tx; + + if (t == QAccessible::Name) + return menu()->windowTitle(); + return tx; +} + +QAccessible::Role QAccessibleMenu::role() const +{ + return QAccessible::PopupMenu; +} + +QAccessibleInterface *QAccessibleMenu::child(int index) const +{ + if (index < childCount()) + return getOrCreateMenu(menu(), menu()->actions().at(index)); + return 0; +} + +QAccessibleInterface *QAccessibleMenu::parent() const +{ + if (QAction *menuAction = menu()->menuAction()) { + QList parentCandidates; + parentCandidates << menu()->parentWidget(); + parentCandidates << menuAction->associatedWidgets(); + foreach (QWidget *w, parentCandidates) { + if (qobject_cast(w) || qobject_cast(w)) { + if (w->actions().indexOf(menuAction) != -1) + return getOrCreateMenu(w, menuAction); + } + } + } + return QAccessibleWidget::parent(); +} + +int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const +{ + QAccessible::Role r = child->role(); + if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) { + return menu()->actions().indexOf(qobject_cast(child->object())); + } + return -1; +} + +#ifndef QT_NO_MENUBAR +QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w) + : QAccessibleWidget(w, QAccessible::MenuBar) +{ + Q_ASSERT(menuBar()); +} + +QMenuBar *QAccessibleMenuBar::menuBar() const +{ + return qobject_cast(object()); +} + +int QAccessibleMenuBar::childCount() const +{ + return menuBar()->actions().count(); +} + +QAccessibleInterface *QAccessibleMenuBar::child(int index) const +{ + if (index < childCount()) { + return getOrCreateMenu(menuBar(), menuBar()->actions().at(index)); + } + return 0; +} + +int QAccessibleMenuBar::indexOfChild(const QAccessibleInterface *child) const +{ + QAccessible::Role r = child->role(); + if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) { + return menuBar()->actions().indexOf(qobject_cast(child->object())); + } + return -1; +} + +#endif // QT_NO_MENUBAR + +QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action) +: m_action(action), m_owner(owner) +{ +} + +QAccessibleMenuItem::~QAccessibleMenuItem() +{} + +QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const +{ + for (int i = childCount() - 1; i >= 0; --i) { + QAccessibleInterface *childInterface = child(i); + if (childInterface->rect().contains(x,y)) { + return childInterface; + } + } + return 0; +} + +int QAccessibleMenuItem::childCount() const +{ + return m_action->menu() ? 1 : 0; +} + +int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const +{ + if (child && child->role() == QAccessible::PopupMenu && child->object() == m_action->menu()) + return 0; + return -1; +} + +bool QAccessibleMenuItem::isValid() const +{ + return m_action && m_owner ? true : false; +} + +QAccessibleInterface *QAccessibleMenuItem::parent() const +{ + return QAccessible::queryAccessibleInterface(owner()); +} + +QAccessibleInterface *QAccessibleMenuItem::child(int index) const +{ + if (index == 0 && action()->menu()) + return QAccessible::queryAccessibleInterface(action()->menu()); + return 0; +} + +void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::ActionInterface) + return static_cast(this); + return 0; +} + +QObject *QAccessibleMenuItem::object() const +{ + return m_action; +} + +QRect QAccessibleMenuItem::rect() const +{ + QRect rect; + QWidget *own = owner(); +#ifndef QT_NO_MENUBAR + if (QMenuBar *menuBar = qobject_cast(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(own)) { + rect = menu->actionGeometry(m_action); + QPoint globalPos = menu->mapToGlobal(QPoint(0,0)); + rect = rect.translated(globalPos); + } + return rect; +} + +QAccessible::Role QAccessibleMenuItem::role() const +{ + return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem; +} + +void QAccessibleMenuItem::setText(QAccessible::Text /*t*/, const QString & /*text */) +{ +} + +QAccessible::State QAccessibleMenuItem::state() const +{ + QAccessible::State s; + QWidget *own = owner(); + + if (own && (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false)) { + s.invisible = true; + } + + if (QMenu *menu = qobject_cast(own)) { + if (menu->activeAction() == m_action) + s.focused = true; +#ifndef QT_NO_MENUBAR + } else if (QMenuBar *menuBar = qobject_cast(own)) { + if (menuBar->activeAction() == m_action) + s.focused = true; +#endif + } + if (own && own->style()->styleHint(QStyle::SH_Menu_MouseTracking)) + s.hotTracked = true; + if (m_action->isSeparator() || !m_action->isEnabled()) + s.disabled = true; + if (m_action->isChecked()) + s.checked = true; + + return s; +} + +QString QAccessibleMenuItem::text(QAccessible::Text t) const +{ + QString str; + switch (t) { + case QAccessible::Name: + str = m_action->text(); + str = qt_accStripAmp(str); + break; + case QAccessible::Accelerator: { +#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; +} + +QStringList QAccessibleMenuItem::actionNames() const +{ + QStringList actions; + if (!m_action || m_action->isSeparator()) + return actions; + + if (m_action->menu()) { + actions << showMenuAction(); + } else { + actions << pressAction(); + } + return actions; +} + +void QAccessibleMenuItem::doAction(const QString &actionName) +{ + if (!m_action->isEnabled()) + return; + + if (actionName == pressAction()) { + m_action->trigger(); + } else if (actionName == showMenuAction()) { + if (QMenuBar *bar = qobject_cast(owner())) { + if (m_action->menu() && m_action->menu()->isVisible()) { + m_action->menu()->hide(); + } else { + bar->setActiveAction(m_action); + } + } else if (QMenu *menu = qobject_cast(owner())){ + if (m_action->menu() && m_action->menu()->isVisible()) { + m_action->menu()->hide(); + } else { + menu->setActiveAction(m_action); + } + } + } +} + +QStringList QAccessibleMenuItem::keyBindingsForAction(const QString &) const +{ + return QStringList(); +} + + +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/widgets/accessible/qaccessiblemenu.h b/src/widgets/accessible/qaccessiblemenu.h new file mode 100644 index 0000000000..e8c9f8af3a --- /dev/null +++ b/src/widgets/accessible/qaccessiblemenu.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACCESSIBLEMENU_H +#define QACCESSIBLEMENU_H + +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +#ifndef QT_NO_MENU +class QMenu; +class QMenuBar; +class QAction; + +class QAccessibleMenu : public QAccessibleWidget +{ +public: + explicit QAccessibleMenu(QWidget *w); + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + int indexOfChild( const QAccessibleInterface *child ) const Q_DECL_OVERRIDE; + +protected: + QMenu *menu() const; +}; + +#ifndef QT_NO_MENUBAR +class QAccessibleMenuBar : public QAccessibleWidget +{ +public: + explicit QAccessibleMenuBar(QWidget *w); + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + +protected: + QMenuBar *menuBar() const; +}; +#endif // QT_NO_MENUBAR + + +class QAccessibleMenuItem : public QAccessibleInterface, public QAccessibleActionInterface +{ +public: + explicit QAccessibleMenuItem(QWidget *owner, QAction *w); + + ~QAccessibleMenuItem(); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface * child) const Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + QObject * object() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + // QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + + QWidget *owner() const; +protected: + QAction *action() const; +private: + QAction *m_action; + QPointer 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/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 4e5fade3f4..8a2e38df7e 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -134,7 +134,7 @@ static int qt_accAmpIndex(const QString &text) #endif } -QString Q_WIDGETS_EXPORT qt_accStripAmp(const QString &text) +QString qt_accStripAmp(const QString &text) { QString newText(text); int ampIndex = qt_accAmpIndex(newText); @@ -144,7 +144,7 @@ QString Q_WIDGETS_EXPORT qt_accStripAmp(const QString &text) return newText.replace(QLatin1String("&&"), QLatin1String("&")); } -QString Q_WIDGETS_EXPORT qt_accHotKey(const QString &text) +QString qt_accHotKey(const QString &text) { int ampIndex = qt_accAmpIndex(text); if (ampIndex != -1) diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp new file mode 100644 index 0000000000..a925dd2708 --- /dev/null +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaccessiblewidgets.h" +#include "qaccessiblemenu.h" +#include "simplewidgets.h" +#include "rangecontrols.h" +#include "complexwidgets.h" +#include "itemviews.h" + +#include +#include +#include +#include +#include + +#ifndef QT_NO_ACCESSIBILITY + +QT_BEGIN_NAMESPACE + +QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *object) +{ + QAccessibleInterface *iface = 0; + if (!object || !object->isWidgetType()) + return iface; + QWidget *widget = static_cast(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")) { + QAccessible::Role role = QAccessible::NoRole; +#ifndef QT_NO_MENU + QToolButton *tb = qobject_cast(widget); + if (!tb->menu()) + role = tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton; + else if (tb->popupMode() == QToolButton::DelayedPopup) + role = QAccessible::ButtonDropDown; + else +#endif + role = QAccessible::ButtonMenu; + iface = new QAccessibleToolButton(widget, role); +#endif // QT_NO_TOOLBUTTON + } else if (classname == QLatin1String("QCheckBox")) { + iface = new QAccessibleButton(widget, QAccessible::CheckBox); + } else if (classname == QLatin1String("QRadioButton")) { + iface = new QAccessibleButton(widget, QAccessible::RadioButton); + } else if (classname == QLatin1String("QPushButton")) { + QAccessible::Role role = QAccessible::NoRole; + QPushButton *pb = qobject_cast(widget); +#ifndef QT_NO_MENU + if (pb->menu()) + role = QAccessible::ButtonMenu; + else +#endif + if (pb->isCheckable()) + role = QAccessible::CheckBox; + else + role = QAccessible::PushButton; + iface = new QAccessibleButton(widget, role); + } else if (classname == QLatin1String("QAbstractButton")) { + iface = new QAccessibleButton(widget, QAccessible::PushButton); + } else if (classname == QLatin1String("QDialog")) { + iface = new QAccessibleWidget(widget, QAccessible::Dialog); + } else if (classname == QLatin1String("QMessageBox")) { + iface = new QAccessibleWidget(widget, QAccessible::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); +#ifndef QT_NO_GROUPBOX + } else if (classname == QLatin1String("QGroupBox")) { + iface = new QAccessibleGroupBox(widget); +#endif + } else if (classname == QLatin1String("QStatusBar")) { + iface = new QAccessibleDisplay(widget); +#ifndef QT_NO_PROGRESSBAR + } else if (classname == QLatin1String("QProgressBar")) { + iface = new QAccessibleProgressBar(widget); +#endif + } else if (classname == QLatin1String("QToolBar")) { + iface = new QAccessibleWidget(widget, QAccessible::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); +#endif +#ifndef QT_NO_ITEMVIEWS + } else if (classname == QLatin1String("QTreeView")) { + iface = new QAccessibleTree(widget); + } else if (classname == QLatin1String("QTableView") || classname == QLatin1String("QListView")) { + iface = new QAccessibleTable(widget); + // ### This should be cleaned up. We return the parent for the scrollarea to hide it. +#endif // QT_NO_ITEMVIEWS +#ifndef QT_NO_TABBAR + } else if (classname == QLatin1String("QTabBar")) { + iface = new QAccessibleTabBar(widget); +#endif + } else if (classname == QLatin1String("QSizeGrip")) { + iface = new QAccessibleWidget(widget, QAccessible::Grip); +#ifndef QT_NO_SPLITTER + } else if (classname == QLatin1String("QSplitter")) { + iface = new QAccessibleWidget(widget, QAccessible::Splitter); + } else if (classname == QLatin1String("QSplitterHandle")) { + iface = new QAccessibleWidget(widget, QAccessible::Grip); +#endif +#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR) + } else if (classname == QLatin1String("QTextEdit")) { + iface = new QAccessibleTextEdit(widget); + } else if (classname == QLatin1String("QPlainTextEdit")) { + iface = new QAccessiblePlainTextEdit(widget); +#endif + } else if (classname == QLatin1String("QTipLabel")) { + iface = new QAccessibleDisplay(widget, QAccessible::ToolTip); + } else if (classname == QLatin1String("QFrame")) { + iface = new QAccessibleWidget(widget, QAccessible::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 + } 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 QAccessibleWidget(widget, QAccessible::Border); +#endif +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) + } 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 + + } else if (classname == QLatin1String("QDesktopScreenWidget")) { + iface = 0; + } else if (classname == QLatin1String("QWidget")) { + iface = new QAccessibleWidget(widget); + } else if (classname == QLatin1String("QWindowContainer")) { + iface = new QAccessibleWindowContainer(widget); + } + + return iface; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/widgets/accessible/qaccessiblewidgetfactory_p.h b/src/widgets/accessible/qaccessiblewidgetfactory_p.h new file mode 100644 index 0000000000..70ac462950 --- /dev/null +++ b/src/widgets/accessible/qaccessiblewidgetfactory_p.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#ifndef QACCESSIBLEWIDGETFACTORY_H +#define QACCESSIBLEWIDGETFACTORY_H + +QT_BEGIN_NAMESPACE + +QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *object); + +QT_END_NAMESPACE + +#endif diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp new file mode 100644 index 0000000000..fa976ea94d --- /dev/null +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -0,0 +1,1019 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $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 "qplaintextedit.h" +#include "qtextboundaryfinder.h" +#include "qscrollbar.h" +#include "qdebug.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_ACCESSIBILITY + +QT_BEGIN_NAMESPACE + +QString qt_accStripAmp(const QString &text); + +QList childWidgets(const QWidget *widget, bool includeTopLevel) +{ + if (widget == 0) + return QList(); + QList list = widget->children(); + QList widgets; + for (int i = 0; i < list.size(); ++i) { + QWidget *w = qobject_cast(list.at(i)); + if (!w) + continue; + QString objectName = w->objectName(); + if ((includeTopLevel || !w->isWindow()) + && !qobject_cast(w) + && !qobject_cast(w) + && objectName != QLatin1String("qt_rubberband") + && objectName != QLatin1String("qt_qmainwindow_extended_splitter")) { + widgets.append(w); + } + } + return widgets; +} + +#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR) + +QAccessiblePlainTextEdit::QAccessiblePlainTextEdit(QWidget* o) + :QAccessibleTextWidget(o) +{ + Q_ASSERT(widget()->inherits("QPlainTextEdit")); +} + +QPlainTextEdit* QAccessiblePlainTextEdit::plainTextEdit() const +{ + return static_cast(widget()); +} + +QString QAccessiblePlainTextEdit::text(QAccessible::Text t) const +{ + if (t == QAccessible::Value) + return plainTextEdit()->toPlainText(); + + return QAccessibleWidget::text(t); +} + +void QAccessiblePlainTextEdit::setText(QAccessible::Text t, const QString &text) +{ + if (t != QAccessible::Value) { + QAccessibleWidget::setText(t, text); + return; + } + if (plainTextEdit()->isReadOnly()) + return; + + plainTextEdit()->setPlainText(text); +} + +QAccessible::State QAccessiblePlainTextEdit::state() const +{ + QAccessible::State st = QAccessibleTextWidget::state(); + if (plainTextEdit()->isReadOnly()) + st.readOnly = true; + else + st.editable = true; + return st; +} + +void *QAccessiblePlainTextEdit::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::TextInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} + +QPoint QAccessiblePlainTextEdit::scrollBarPosition() const +{ + QPoint result; + result.setX(plainTextEdit()->horizontalScrollBar() ? plainTextEdit()->horizontalScrollBar()->sliderPosition() : 0); + result.setY(plainTextEdit()->verticalScrollBar() ? plainTextEdit()->verticalScrollBar()->sliderPosition() : 0); + return result; +} + +QTextCursor QAccessiblePlainTextEdit::textCursor() const +{ + return plainTextEdit()->textCursor(); +} + +void QAccessiblePlainTextEdit::setTextCursor(const QTextCursor &textCursor) +{ + plainTextEdit()->setTextCursor(textCursor); +} + +QTextDocument* QAccessiblePlainTextEdit::textDocument() const +{ + return plainTextEdit()->document(); +} + +QWidget* QAccessiblePlainTextEdit::viewport() const +{ + return plainTextEdit()->viewport(); +} + +void QAccessiblePlainTextEdit::scrollToSubstring(int startIndex, int endIndex) +{ + //TODO: Not implemented + Q_UNUSED(startIndex); + Q_UNUSED(endIndex); +} + + +/*! + \class QAccessibleTextEdit + \brief The QAccessibleTextEdit class implements the QAccessibleInterface for richtext editors. + \internal +*/ + +/*! + \fn QAccessibleTextEdit::QAccessibleTextEdit(QWidget *widget) + + Constructs a QAccessibleTextEdit object for a \a widget. +*/ +QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o) +: QAccessibleTextWidget(o, QAccessible::EditableText) +{ + Q_ASSERT(widget()->inherits("QTextEdit")); +} + +/*! Returns the text edit. */ +QTextEdit *QAccessibleTextEdit::textEdit() const +{ + return static_cast(widget()); +} + +QTextCursor QAccessibleTextEdit::textCursor() const +{ + return textEdit()->textCursor(); +} + +QTextDocument *QAccessibleTextEdit::textDocument() const +{ + return textEdit()->document(); +} + +void QAccessibleTextEdit::setTextCursor(const QTextCursor &textCursor) +{ + textEdit()->setTextCursor(textCursor); +} + +QWidget *QAccessibleTextEdit::viewport() const +{ + return textEdit()->viewport(); +} + +QPoint QAccessibleTextEdit::scrollBarPosition() const +{ + QPoint result; + result.setX(textEdit()->horizontalScrollBar() ? textEdit()->horizontalScrollBar()->sliderPosition() : 0); + result.setY(textEdit()->verticalScrollBar() ? textEdit()->verticalScrollBar()->sliderPosition() : 0); + return result; +} + +QString QAccessibleTextEdit::text(QAccessible::Text t) const +{ + if (t == QAccessible::Value) + return textEdit()->toPlainText(); + + return QAccessibleWidget::text(t); +} + +void QAccessibleTextEdit::setText(QAccessible::Text t, const QString &text) +{ + if (t != QAccessible::Value) { + QAccessibleWidget::setText(t, text); + return; + } + if (textEdit()->isReadOnly()) + return; + + textEdit()->setText(text); +} + +QAccessible::State QAccessibleTextEdit::state() const +{ + QAccessible::State st = QAccessibleTextWidget::state(); + if (textEdit()->isReadOnly()) + st.readOnly = true; + else + st.editable = true; + return st; +} + +void *QAccessibleTextEdit::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::TextInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} + +void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex) +{ + QTextEdit *edit = textEdit(); + + QTextCursor cursor = textCursor(); + 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!"); +} + +#endif // QT_NO_TEXTEDIT && QT_NO_CURSOR + +#ifndef QT_NO_STACKEDWIDGET +// ======================= QAccessibleStackedWidget ====================== +QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::LayeredPane) +{ + Q_ASSERT(qobject_cast(widget)); +} + +QAccessibleInterface *QAccessibleStackedWidget::childAt(int x, int y) const +{ + if (!stackedWidget()->isVisible()) + return 0; + QWidget *currentWidget = stackedWidget()->currentWidget(); + if (!currentWidget) + return 0; + QPoint position = currentWidget->mapFromGlobal(QPoint(x, y)); + if (currentWidget->rect().contains(position)) + return child(stackedWidget()->currentIndex()); + return 0; +} + +int QAccessibleStackedWidget::childCount() const +{ + return stackedWidget()->count(); +} + +int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const +{ + if (!child) + return -1; + + QWidget *widget = qobject_cast(child->object()); + return stackedWidget()->indexOf(widget); +} + +QAccessibleInterface *QAccessibleStackedWidget::child(int index) const +{ + if (index < 0 || index >= stackedWidget()->count()) + return 0; + return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index)); +} + +QStackedWidget *QAccessibleStackedWidget::stackedWidget() const +{ + return static_cast(object()); +} +#endif // QT_NO_STACKEDWIDGET + +#ifndef QT_NO_TOOLBOX +// ======================= QAccessibleToolBox ====================== +QAccessibleToolBox::QAccessibleToolBox(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::LayeredPane) +{ + Q_ASSERT(qobject_cast(widget)); +} + +QToolBox * QAccessibleToolBox::toolBox() const +{ + return static_cast(object()); +} +#endif // QT_NO_TOOLBOX + +// ======================= QAccessibleMdiArea ====================== +#ifndef QT_NO_MDIAREA +QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::LayeredPane) +{ + Q_ASSERT(qobject_cast(widget)); +} + +int QAccessibleMdiArea::childCount() const +{ + return mdiArea()->subWindowList().count(); +} + +QAccessibleInterface *QAccessibleMdiArea::child(int index) const +{ + QList subWindows = mdiArea()->subWindowList(); + QWidget *targetObject = subWindows.value(index); + if (!targetObject) + return 0; + return QAccessible::queryAccessibleInterface(targetObject); +} + + +int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const +{ + if (!child || !child->object() || mdiArea()->subWindowList().isEmpty()) + return -1; + if (QMdiSubWindow *window = qobject_cast(child->object())) { + return mdiArea()->subWindowList().indexOf(window); + } + return -1; +} + +QMdiArea *QAccessibleMdiArea::mdiArea() const +{ + return static_cast(object()); +} + +// ======================= QAccessibleMdiSubWindow ====================== +QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Window) +{ + Q_ASSERT(qobject_cast(widget)); +} + +QString QAccessibleMdiSubWindow::text(QAccessible::Text textType) const +{ + if (textType == QAccessible::Name) { + QString title = mdiSubWindow()->windowTitle(); + title.replace(QLatin1String("[*]"), QLatin1String("")); + return title; + } + return QAccessibleWidget::text(textType); +} + +void QAccessibleMdiSubWindow::setText(QAccessible::Text textType, const QString &text) +{ + if (textType == QAccessible::Name) + mdiSubWindow()->setWindowTitle(text); + else + QAccessibleWidget::setText(textType, text); +} + +QAccessible::State QAccessibleMdiSubWindow::state() const +{ + QAccessible::State state; + state.focusable = true; + if (!mdiSubWindow()->isMaximized()) { + state.movable = true; + state.sizeable = true; + } + if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget()) + || QApplication::focusWidget() == mdiSubWindow()) + state.focused = true; + if (!mdiSubWindow()->isVisible()) + state.invisible = true; + if (const QWidget *parent = mdiSubWindow()->parentWidget()) + if (!parent->contentsRect().contains(mdiSubWindow()->geometry())) + state.offscreen = true; + if (!mdiSubWindow()->isEnabled()) + state.disabled = true; + return state; +} + +int QAccessibleMdiSubWindow::childCount() const +{ + if (mdiSubWindow()->widget()) + return 1; + return 0; +} + +QAccessibleInterface *QAccessibleMdiSubWindow::child(int index) const +{ + QMdiSubWindow *source = mdiSubWindow(); + if (index != 0 || !source->widget()) + return 0; + + return QAccessible::queryAccessibleInterface(source->widget()); +} + +int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const +{ + if (child && child->object() && child->object() == mdiSubWindow()->widget()) + return 0; + return -1; +} + +QRect QAccessibleMdiSubWindow::rect() const +{ + if (mdiSubWindow()->isHidden()) + return QRect(); + if (!mdiSubWindow()->parent()) + return QAccessibleWidget::rect(); + const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0)); + return QRect(pos, mdiSubWindow()->size()); +} + +QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const +{ + return static_cast(object()); +} +#endif // QT_NO_MDIAREA + +#ifndef QT_NO_DIALOGBUTTONBOX +// ======================= QAccessibleDialogButtonBox ====================== +QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Grouping) +{ + Q_ASSERT(qobject_cast(widget)); +} + +#endif // QT_NO_DIALOGBUTTONBOX + +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) +QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget) + : QAccessibleTextEdit(widget) +{ + Q_ASSERT(qobject_cast(widget)); +} + +QAccessible::Role QAccessibleTextBrowser::role() const +{ + return QAccessible::StaticText; +} +#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR + +#ifndef QT_NO_CALENDARWIDGET +// ===================== QAccessibleCalendarWidget ======================== +QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Table) +{ + Q_ASSERT(qobject_cast(widget)); +} + +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(child->object())) + return childCount() - 1; // FIXME + return 0; +} + +QAccessibleInterface *QAccessibleCalendarWidget::child(int index) const +{ + if (index < 0 || index >= childCount()) + return 0; + + if (childCount() > 1 && index == 0) + return QAccessible::queryAccessibleInterface(navigationBar()); + + return QAccessible::queryAccessibleInterface(calendarView()); +} + +QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const +{ + return static_cast(object()); +} + +QAbstractItemView *QAccessibleCalendarWidget::calendarView() const +{ + foreach (QObject *child, calendarWidget()->children()) { + if (child->objectName() == QLatin1String("qt_calendar_calendarview")) + return static_cast(child); + } + return 0; +} + +QWidget *QAccessibleCalendarWidget::navigationBar() const +{ + foreach (QObject *child, calendarWidget()->children()) { + if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) + return static_cast(child); + } + return 0; +} +#endif // QT_NO_CALENDARWIDGET + +#ifndef QT_NO_DOCKWIDGET + +// Dock Widget - order of children: +// - Content widget +// - Float button +// - Close button +// If there is a custom title bar widget, that one becomes child 1, after the content 0 +// (in that case the buttons are ignored) +QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Window) +{ +} + +QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const +{ + return qobject_cast(dockWidget()->layout()); +} + +int QAccessibleDockWidget::childCount() const +{ + if (dockWidget()->titleBarWidget()) { + return dockWidget()->widget() ? 2 : 1; + } + return dockWidgetLayout()->count(); +} + +QAccessibleInterface *QAccessibleDockWidget::child(int index) const +{ + if (dockWidget()->titleBarWidget()) { + if ((!dockWidget()->widget() && index == 0) || (index == 1)) + return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget()); + if (index == 0) + return QAccessible::queryAccessibleInterface(dockWidget()->widget()); + } else { + QLayoutItem *item = dockWidgetLayout()->itemAt(index); + if (item) + return QAccessible::queryAccessibleInterface(item->widget()); + } + return 0; +} + +int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const +{ + if (!child || !child->object() || child->object()->parent() != object()) + return -1; + + if (dockWidget()->titleBarWidget() == child->object()) { + return dockWidget()->widget() ? 1 : 0; + } + + return dockWidgetLayout()->indexOf(qobject_cast(child->object())); +} + +QRect QAccessibleDockWidget::rect() const +{ + QRect rect; + + if (dockWidget()->isFloating()) { + rect = dockWidget()->frameGeometry(); + } else { + rect = dockWidget()->rect(); + rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); + } + + return rect; +} + +QDockWidget *QAccessibleDockWidget::dockWidget() const +{ + return static_cast(object()); +} + +QString QAccessibleDockWidget::text(QAccessible::Text t) const +{ + if (t == QAccessible::Name) { + return qt_accStripAmp(dockWidget()->windowTitle()); + } + return QString(); +} +#endif // QT_NO_DOCKWIDGET + +#ifndef QT_NO_CURSOR + +QAccessibleTextWidget::QAccessibleTextWidget(QWidget *o, QAccessible::Role r, const QString &name): + QAccessibleWidget(o, r, name) +{ + +} + +QAccessible::State QAccessibleTextWidget::state() const +{ + QAccessible::State s = QAccessibleWidget::state(); + s.multiLine = true; + return s; +} + +QRect QAccessibleTextWidget::characterRect(int offset) const +{ + QTextBlock block = textDocument()->findBlock(offset); + if (!block.isValid()) + return QRect(); + + QTextLayout *layout = block.layout(); + QPointF layoutPosition = layout->position(); + int relativeOffset = offset - block.position(); + QTextLine line = layout->lineForTextPosition(relativeOffset); + + QRect r; + + if (line.isValid()) { + qreal x = line.cursorToX(relativeOffset); + QFontMetrics fm(textCursor().charFormat().font()); + const QString ch = text(offset, offset + 1); + if (!ch.isEmpty()) { + int w = fm.width(ch); + int h = fm.height(); + r = QRect(layoutPosition.x() + x, layoutPosition.y() + line.y(), + w, h); + r.moveTo(viewport()->mapToGlobal(r.topLeft())); + } + r.translate(-scrollBarPosition()); + } + + return r; +} + +int QAccessibleTextWidget::offsetAtPoint(const QPoint &point) const +{ + QPoint p = viewport()->mapFromGlobal(point); + // convert to document coordinates + p += scrollBarPosition(); + return textDocument()->documentLayout()->hitTest(p, Qt::ExactHit); +} + +int QAccessibleTextWidget::selectionCount() const +{ + return textCursor().hasSelection() ? 1 : 0; +} + +QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *endOffset) const +{ + /* The list of attributes can be found at: + http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes + */ + + if (offset >= characterCount()) { + *startOffset = -1; + *endOffset = -1; + return QString(); + } + + QMap attrs; + + QTextCursor cursor = textCursor(); + + //cursor.charFormat returns the format of the previous character + cursor.setPosition(offset + 1); + QTextCharFormat charFormat = cursor.charFormat(); + + cursor.setPosition(offset); + QTextBlockFormat blockFormat = cursor.blockFormat(); + + QTextCharFormat charFormatComp; + QTextBlockFormat blockFormatComp; + + *startOffset = offset; + cursor.setPosition(*startOffset); + while (*startOffset > 0) { + charFormatComp = cursor.charFormat(); + cursor.setPosition(*startOffset - 1); + blockFormatComp = cursor.blockFormat(); + if ((charFormat == charFormatComp) && (blockFormat == blockFormatComp)) + (*startOffset)--; + else + break; + } + + int limit = characterCount() + 1; + *endOffset = offset + 1; + cursor.setPosition(*endOffset); + while (*endOffset < limit) { + blockFormatComp = cursor.blockFormat(); + cursor.setPosition(*endOffset + 1); + charFormatComp = cursor.charFormat(); + if ((charFormat == charFormatComp) && (cursor.blockFormat() == blockFormatComp)) + (*endOffset)++; + else + break; + } + + QString family = charFormat.fontFamily(); + if (!family.isEmpty()) { + family = family.replace('\\',"\\\\"); + family = family.replace(':',"\\:"); + family = family.replace(',',"\\,"); + family = family.replace('=',"\\="); + family = family.replace(';',"\\;"); + family = family.replace('\"',"\\\""); + attrs["font-family"] = '"'+family+'"'; + } + + int fontSize = int(charFormat.fontPointSize()); + if (fontSize) + attrs["font-size"] = QString::number(fontSize).append("pt"); + + //Different weight values are not handled + attrs["font-weight"] = (charFormat.fontWeight() > QFont::Normal) ? "bold" : "normal"; + + QFont::Style style = charFormat.font().style(); + attrs["font-style"] = (style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal"); + + attrs["text-underline-style"] = charFormat.font().underline() ? "solid" : "none"; + + QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment(); + attrs["text-position"] = (alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" ); + + QBrush background = charFormat.background(); + if (background.style() == Qt::SolidPattern) { + attrs["background-color"] = QString("rgb(%1,%2,%3)").arg(background.color().red()).arg(background.color().green()).arg(background.color().blue()); + } + + QBrush foreground = charFormat.foreground(); + if (foreground.style() == Qt::SolidPattern) { + attrs["color"] = QString("rgb(%1,%2,%3)").arg(foreground.color().red()).arg(foreground.color().green()).arg(foreground.color().blue()); + } + + switch (blockFormat.alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)) { + case Qt::AlignLeft: + attrs["text-align"] = "left"; + break; + case Qt::AlignRight: + attrs["text-align"] = "right"; + break; + case Qt::AlignHCenter: + attrs["text-align"] = "center"; + break; + case Qt::AlignJustify: + attrs["text-align"] = "left"; + break; + } + + QString result; + foreach (const QString &attributeName, attrs.keys()) { + result.append(attributeName).append(':').append(attrs[attributeName]).append(';'); + } + + return result; +} + +int QAccessibleTextWidget::cursorPosition() const +{ + return textCursor().position(); +} + +void QAccessibleTextWidget::selection(int selectionIndex, int *startOffset, int *endOffset) const +{ + *startOffset = *endOffset = 0; + QTextCursor cursor = textCursor(); + + if (selectionIndex != 0 || !cursor.hasSelection()) + return; + + *startOffset = cursor.selectionStart(); + *endOffset = cursor.selectionEnd(); +} + +QString QAccessibleTextWidget::text(int startOffset, int endOffset) const +{ + QTextCursor cursor(textCursor()); + + cursor.setPosition(startOffset, QTextCursor::MoveAnchor); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + + return cursor.selectedText(); +} + +QPoint QAccessibleTextWidget::scrollBarPosition() const +{ + return QPoint(0, 0); +} + + +QString QAccessibleTextWidget::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + QTextCursor cursor = textCursor(); + cursor.setPosition(offset); + QPair boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + cursor.setPosition(boundaries.first - 1); + boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return text(boundaries.first, boundaries.second); + } + + +QString QAccessibleTextWidget::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + QTextCursor cursor = textCursor(); + cursor.setPosition(offset); + QPair boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + cursor.setPosition(boundaries.second); + boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return text(boundaries.first, boundaries.second); +} + +QString QAccessibleTextWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + QTextCursor cursor = textCursor(); + cursor.setPosition(offset); + QPair boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return text(boundaries.first, boundaries.second); +} + +void QAccessibleTextWidget::setCursorPosition(int position) +{ + QTextCursor cursor = textCursor(); + cursor.setPosition(position); + setTextCursor(cursor); +} + +void QAccessibleTextWidget::addSelection(int startOffset, int endOffset) +{ + setSelection(0, startOffset, endOffset); +} + +void QAccessibleTextWidget::removeSelection(int selectionIndex) +{ + if (selectionIndex != 0) + return; + + QTextCursor cursor = textCursor(); + cursor.clearSelection(); + setTextCursor(cursor); +} + +void QAccessibleTextWidget::setSelection(int selectionIndex, int startOffset, int endOffset) +{ + if (selectionIndex != 0) + return; + + QTextCursor cursor = textCursor(); + cursor.setPosition(startOffset, QTextCursor::MoveAnchor); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + setTextCursor(cursor); +} + +int QAccessibleTextWidget::characterCount() const +{ + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::End); + return cursor.position(); +} + +QTextCursor QAccessibleTextWidget::textCursorForRange(int startOffset, int endOffset) const +{ + QTextCursor cursor = textCursor(); + cursor.setPosition(startOffset, QTextCursor::MoveAnchor); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + + return cursor; +} + +void QAccessibleTextWidget::deleteText(int startOffset, int endOffset) +{ + QTextCursor cursor = textCursorForRange(startOffset, endOffset); + cursor.removeSelectedText(); +} + +void QAccessibleTextWidget::insertText(int offset, const QString &text) +{ + QTextCursor cursor = textCursor(); + cursor.setPosition(offset); + cursor.insertText(text); +} + +void QAccessibleTextWidget::replaceText(int startOffset, int endOffset, const QString &text) +{ + QTextCursor cursor = textCursorForRange(startOffset, endOffset); + cursor.removeSelectedText(); + cursor.insertText(text); +} +#endif // QT_NO_CURSOR + + +#ifndef QT_NO_MAINWINDOW +QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Window) { } + +QAccessibleInterface *QAccessibleMainWindow::child(int index) const +{ + QList kids = childWidgets(mainWindow(), true); + if (index >= 0 && index < kids.count()) { + return QAccessible::queryAccessibleInterface(kids.at(index)); + } + return 0; +} + +int QAccessibleMainWindow::childCount() const +{ + QList kids = childWidgets(mainWindow(), true); + return kids.count(); +} + +int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const +{ + QList kids = childWidgets(mainWindow(), true); + return kids.indexOf(static_cast(iface->object())); +} + +QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const +{ + QWidget *w = widget(); + if (!w->isVisible()) + return 0; + QPoint gp = w->mapToGlobal(QPoint(0, 0)); + if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y)) + return 0; + + 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 QAccessible::queryAccessibleInterface(child); + } + } + return 0; +} + +QMainWindow *QAccessibleMainWindow::mainWindow() const +{ + return qobject_cast(object()); +} + +#endif //QT_NO_MAINWINDOW + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/widgets/accessible/qaccessiblewidgets.h b/src/widgets/accessible/qaccessiblewidgets.h new file mode 100644 index 0000000000..3f50010685 --- /dev/null +++ b/src/widgets/accessible/qaccessiblewidgets.h @@ -0,0 +1,314 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACCESSIBLEWIDGETS_H +#define QACCESSIBLEWIDGETS_H + +#include + +#ifndef QT_NO_ACCESSIBILITY + +#include +#include + +QT_BEGIN_NAMESPACE + +class QTextEdit; +class QStackedWidget; +class QToolBox; +class QMdiArea; +class QMdiSubWindow; +class QRubberBand; +class QTextBrowser; +class QCalendarWidget; +class QAbstractItemView; +class QDockWidget; +class QDockWidgetLayout; +class QMainWindow; +class QPlainTextEdit; +class QTextCursor; +class QTextDocument; + +#ifndef QT_NO_CURSOR +class QAccessibleTextWidget : public QAccessibleWidget, + public QAccessibleTextInterface, + public QAccessibleEditableTextInterface +{ +public: + QAccessibleTextWidget(QWidget *o, QAccessible::Role r = QAccessible::EditableText, const QString &name = QString()); + + QAccessible::State state() const; + + // QAccessibleTextInterface + // selection + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; + + // cursor + int cursorPosition() const Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; + + // text + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; + QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int characterCount() const; + + // character <-> geometry + QRect characterRect(int offset) const Q_DECL_OVERRIDE; + int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; + + QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + + // QAccessibleEditableTextInterface + void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; + void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; + + using QAccessibleWidget::text; + +protected: + QTextCursor textCursorForRange(int startOffset, int endOffset) const; + virtual QPoint scrollBarPosition() const; + // return the current text cursor at the caret position including a potential selection + virtual QTextCursor textCursor() const = 0; + virtual void setTextCursor(const QTextCursor &) = 0; + virtual QTextDocument *textDocument() const = 0; + virtual QWidget *viewport() const = 0; +}; + +#ifndef QT_NO_TEXTEDIT +class QAccessiblePlainTextEdit : public QAccessibleTextWidget +{ +public: + explicit QAccessiblePlainTextEdit(QWidget *o); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + using QAccessibleTextWidget::text; + +protected: + QPlainTextEdit *plainTextEdit() const; + + QPoint scrollBarPosition() const Q_DECL_OVERRIDE; + QTextCursor textCursor() const Q_DECL_OVERRIDE; + void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; + QTextDocument *textDocument() const Q_DECL_OVERRIDE; + QWidget *viewport() const Q_DECL_OVERRIDE; +}; + +class QAccessibleTextEdit : public QAccessibleTextWidget +{ +public: + explicit QAccessibleTextEdit(QWidget *o); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + using QAccessibleTextWidget::text; + +protected: + QTextEdit *textEdit() const; + + QPoint scrollBarPosition() const Q_DECL_OVERRIDE; + QTextCursor textCursor() const Q_DECL_OVERRIDE; + void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; + QTextDocument *textDocument() const Q_DECL_OVERRIDE; + QWidget *viewport() const Q_DECL_OVERRIDE; +}; +#endif // QT_NO_TEXTEDIT +#endif //QT_NO_CURSOR + +class QAccessibleStackedWidget : public QAccessibleWidget +{ +public: + explicit QAccessibleStackedWidget(QWidget *widget); + + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +protected: + QStackedWidget *stackedWidget() const; +}; + +class QAccessibleToolBox : public QAccessibleWidget +{ +public: + explicit QAccessibleToolBox(QWidget *widget); + +// FIXME we currently expose the toolbox but it is not keyboard navigatable +// and the accessible hierarchy is not exactly beautiful. +// int childCount() const; +// QAccessibleInterface *child(int index) const; +// int indexOfChild(const QAccessibleInterface *child) const; + +protected: + QToolBox *toolBox() const; +}; + +#ifndef QT_NO_MDIAREA +class QAccessibleMdiArea : public QAccessibleWidget +{ +public: + explicit QAccessibleMdiArea(QWidget *widget); + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + +protected: + QMdiArea *mdiArea() const; +}; + +class QAccessibleMdiSubWindow : public QAccessibleWidget +{ +public: + explicit QAccessibleMdiSubWindow(QWidget *widget); + + QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text textType, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + +protected: + QMdiSubWindow *mdiSubWindow() const; +}; +#endif // QT_NO_MDIAREA + +class QAccessibleDialogButtonBox : public QAccessibleWidget +{ +public: + explicit QAccessibleDialogButtonBox(QWidget *widget); +}; + +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) +class QAccessibleTextBrowser : public QAccessibleTextEdit +{ +public: + explicit QAccessibleTextBrowser(QWidget *widget); + + QAccessible::Role role() const Q_DECL_OVERRIDE; +}; +#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR + +#ifndef QT_NO_CALENDARWIDGET +class QAccessibleCalendarWidget : public QAccessibleWidget +{ +public: + explicit QAccessibleCalendarWidget(QWidget *widget); + + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +protected: + QCalendarWidget *calendarWidget() const; + +private: + QAbstractItemView *calendarView() const; + QWidget *navigationBar() const; +}; +#endif // QT_NO_CALENDARWIDGET + +#ifndef QT_NO_DOCKWIDGET +class QAccessibleDockWidget: public QAccessibleWidget +{ +public: + explicit QAccessibleDockWidget(QWidget *widget); + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + QRect rect () const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + QDockWidget *dockWidget() const; +protected: + QDockWidgetLayout *dockWidgetLayout() const; +}; + +#endif // QT_NO_DOCKWIDGET + +#ifndef QT_NO_MAINWINDOW +class QAccessibleMainWindow : public QAccessibleWidget +{ +public: + explicit QAccessibleMainWindow(QWidget *widget); + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + QMainWindow *mainWindow() const; + +}; +#endif //QT_NO_MAINWINDOW + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // QACESSIBLEWIDGETS_H diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp new file mode 100644 index 0000000000..d2917e535c --- /dev/null +++ b/src/widgets/accessible/rangecontrols.cpp @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "rangecontrols.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY +QString 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) +: QAccessibleWidget(w, QAccessible::SpinBox) +{ + Q_ASSERT(abstractSpinBox()); +} + +/*! + Returns the underlying QAbstractSpinBox. +*/ +QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const +{ + return qobject_cast(object()); +} + +QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const +{ + if (t == QAccessible::Value) + return abstractSpinBox()->text(); + return QAccessibleWidget::text(t); +} + +void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::ValueInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} + +QVariant QAccessibleAbstractSpinBox::currentValue() const +{ + 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("value", value); +} + +QVariant QAccessibleAbstractSpinBox::maximumValue() const +{ + return abstractSpinBox()->property("maximum"); +} + +QVariant QAccessibleAbstractSpinBox::minimumValue() const +{ + return abstractSpinBox()->property("minimum"); +} + +QVariant QAccessibleAbstractSpinBox::minimumStepSize() const +{ + return abstractSpinBox()->property("stepSize"); +} + +/*! + \class QAccessibleSpinBox + \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets. + \internal + + \ingroup accessibility +*/ + +/*! + 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(object()); +} + + +// ================================== QAccessibleDoubleSpinBox ================================== +QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget) + : QAccessibleAbstractSpinBox(widget) +{ + Q_ASSERT(qobject_cast(widget)); + addControllingSignal(QLatin1String("valueChanged(double)")); + addControllingSignal(QLatin1String("valueChanged(QString)")); +} + +/*! + Returns the underlying QDoubleSpinBox. +*/ +QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const +{ + return static_cast(object()); +} + +QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const +{ + if (textType == QAccessible::Value) + return doubleSpinBox()->textFromValue(doubleSpinBox()->value()); + return QAccessibleWidget::text(textType); +} + +#endif // QT_NO_SPINBOX + +#ifndef QT_NO_SCROLLBAR +/*! + \class QAccessibleScrollBar + \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars. + \internal + + \ingroup accessibility +*/ + +/*! + Constructs a QAccessibleScrollBar object for \a w. + \a name is propagated to the QAccessibleWidget constructor. +*/ +QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w) +: QAccessibleAbstractSlider(w, QAccessible::ScrollBar) +{ + Q_ASSERT(scrollBar()); + addControllingSignal(QLatin1String("valueChanged(int)")); +} + +/*! Returns the scroll bar. */ +QScrollBar *QAccessibleScrollBar::scrollBar() const +{ + return qobject_cast(object()); +} + +QString QAccessibleScrollBar::text(QAccessible::Text t) const +{ + if (t == QAccessible::Value) + return QString::number(scrollBar()->value()); + return QAccessibleAbstractSlider::text(t); +} + +#endif // QT_NO_SCROLLBAR + +#ifndef QT_NO_SLIDER +/*! + \class QAccessibleSlider + \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders. + \internal + + \ingroup accessibility +*/ + +/*! + Constructs a QAccessibleScrollBar object for \a w. + \a name is propagated to the QAccessibleWidget constructor. +*/ +QAccessibleSlider::QAccessibleSlider(QWidget *w) +: QAccessibleAbstractSlider(w) +{ + Q_ASSERT(slider()); + addControllingSignal(QLatin1String("valueChanged(int)")); +} + +/*! Returns the slider. */ +QSlider *QAccessibleSlider::slider() const +{ + return qobject_cast(object()); +} + +QString QAccessibleSlider::text(QAccessible::Text t) const +{ + if (t == QAccessible::Value) + return QString::number(slider()->value()); + + return QAccessibleAbstractSlider::text(t); +} + +QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r) + : QAccessibleWidget(w, r) +{ + Q_ASSERT(qobject_cast(w)); +} + +void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::ValueInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} + +QVariant QAccessibleAbstractSlider::currentValue() const +{ + return abstractSlider()->value(); +} + +void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value) +{ + abstractSlider()->setValue(value.toInt()); +} + +QVariant QAccessibleAbstractSlider::maximumValue() const +{ + return abstractSlider()->maximum(); +} + +QVariant QAccessibleAbstractSlider::minimumValue() const +{ + return abstractSlider()->minimum(); +} + +QVariant QAccessibleAbstractSlider::minimumStepSize() const +{ + return abstractSlider()->singleStep(); +} + +QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const +{ + return static_cast(object()); +} + +#endif // QT_NO_SLIDER + +#ifndef QT_NO_DIAL +// ======================================= QAccessibleDial ====================================== +QAccessibleDial::QAccessibleDial(QWidget *widget) + : QAccessibleAbstractSlider(widget, QAccessible::Dial) +{ + Q_ASSERT(qobject_cast(widget)); + addControllingSignal(QLatin1String("valueChanged(int)")); +} + +QString QAccessibleDial::text(QAccessible::Text textType) const +{ + if (textType == QAccessible::Value) + return QString::number(dial()->value()); + + return QAccessibleAbstractSlider::text(textType); +} + +QDial *QAccessibleDial::dial() const +{ + return static_cast(object()); +} +#endif // QT_NO_DIAL + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE diff --git a/src/widgets/accessible/rangecontrols.h b/src/widgets/accessible/rangecontrols.h new file mode 100644 index 0000000000..dd69788bb1 --- /dev/null +++ b/src/widgets/accessible/rangecontrols.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RANGECONTROLS_H +#define RANGECONTROLS_H + +#include + +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 QAccessibleWidget, public QAccessibleValueInterface // TODO, public QAccessibleActionInterface +{ +public: + explicit QAccessibleAbstractSpinBox(QWidget *w); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleValueInterface + QVariant currentValue() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; + + // FIXME Action interface + +protected: + QAbstractSpinBox *abstractSpinBox() const; +}; + +class QAccessibleSpinBox : public QAccessibleAbstractSpinBox +{ +public: + explicit QAccessibleSpinBox(QWidget *w); + +protected: + QSpinBox *spinBox() const; +}; + +class QAccessibleDoubleSpinBox : public QAccessibleAbstractSpinBox +{ +public: + explicit QAccessibleDoubleSpinBox(QWidget *widget); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + +protected: + QDoubleSpinBox *doubleSpinBox() const; +}; +#endif // QT_NO_SPINBOX + +class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface +{ +public: + explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleValueInterface + QVariant currentValue() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; + +protected: + QAbstractSlider *abstractSlider() const; +}; + +#ifndef QT_NO_SCROLLBAR +class QAccessibleScrollBar : public QAccessibleAbstractSlider +{ +public: + explicit QAccessibleScrollBar(QWidget *w); + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + +protected: + QScrollBar *scrollBar() const; +}; +#endif // QT_NO_SCROLLBAR + +#ifndef QT_NO_SLIDER +class QAccessibleSlider : public QAccessibleAbstractSlider +{ +public: + explicit QAccessibleSlider(QWidget *w); + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + +protected: + QSlider *slider() const; +}; +#endif // QT_NO_SLIDER + +#ifndef QT_NO_DIAL +class QAccessibleDial : public QAccessibleAbstractSlider +{ +public: + explicit QAccessibleDial(QWidget *w); + + QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; + +protected: + QDial *dial() const; +}; +#endif // QT_NO_DIAL + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // RANGECONTROLS_H diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp new file mode 100644 index 0000000000..b729e66d3c --- /dev/null +++ b/src/widgets/accessible/simplewidgets.cpp @@ -0,0 +1,886 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "simplewidgets.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_MAC +#include +#endif + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +extern QList childWidgets(const QWidget *widget, bool includeTopLevel = false); + +QString qt_accStripAmp(const QString &text); +QString 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 QAccessibleWidget constructor. +*/ +QAccessibleButton::QAccessibleButton(QWidget *w, QAccessible::Role role) +: QAccessibleWidget(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(object()); +} + +/*! \reimp */ +QString QAccessibleButton::text(QAccessible::Text t) const +{ + QString str; + switch (t) { + case QAccessible::Accelerator: + { +#ifndef QT_NO_SHORTCUT + QPushButton *pb = qobject_cast(object()); + if (pb && pb->isDefault()) + str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText); +#endif + if (str.isEmpty()) + str = qt_accHotKey(button()->text()); + } + break; + case QAccessible::Name: + str = widget()->accessibleName(); + if (str.isEmpty()) + str = button()->text(); + break; + default: + break; + } + if (str.isEmpty()) + str = QAccessibleWidget::text(t); + return qt_accStripAmp(str); +} + +QAccessible::State QAccessibleButton::state() const +{ + QAccessible::State state = QAccessibleWidget::state(); + + QAbstractButton *b = button(); + QCheckBox *cb = qobject_cast(b); + if (b->isChecked()) + state.checked = true; + else if (cb && cb->checkState() == Qt::PartiallyChecked) + state.checkStateMixed = true; + if (b->isDown()) + state.pressed = true; + QPushButton *pb = qobject_cast(b); + if (pb) { + if (pb->isDefault()) + state.defaultButton = true; +#ifndef QT_NO_MENU + if (pb->menu()) + state.hasPopup = true; +#endif + } + + return state; +} + +QStringList QAccessibleButton::actionNames() const +{ + QStringList names; + if (widget()->isEnabled()) { + switch (role()) { + case QAccessible::ButtonMenu: + names << showMenuAction(); + break; + case QAccessible::RadioButton: + names << toggleAction(); + break; + default: + if (button()->isCheckable()) { + names << toggleAction(); + } else { + names << pressAction(); + } + break; + } + } + names << QAccessibleWidget::actionNames(); + return names; +} + +void QAccessibleButton::doAction(const QString &actionName) +{ + if (!widget()->isEnabled()) + return; + if (actionName == pressAction() || + actionName == showMenuAction()) { +#ifndef QT_NO_MENU + QPushButton *pb = qobject_cast(object()); + if (pb && pb->menu()) + pb->showMenu(); + else +#endif + button()->animateClick(); + } else if (actionName == toggleAction()) { + button()->toggle(); + } else { + QAccessibleWidget::doAction(actionName); + } +} + +QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) const +{ + if (actionName == pressAction()) { +#ifndef QT_NO_SHORTCUT + return QStringList() << button()->shortcut().toString(); +#endif + } + return QStringList(); +} + + +#ifndef QT_NO_TOOLBUTTON +/*! + \class QAccessibleToolButton + \brief The QAccessibleToolButton class implements the QAccessibleInterface for tool buttons. + \internal + + \ingroup accessibility +*/ + +/*! + Creates a QAccessibleToolButton object for \a w. + \a role is propagated to the QAccessibleWidget constructor. +*/ +QAccessibleToolButton::QAccessibleToolButton(QWidget *w, QAccessible::Role role) +: QAccessibleButton(w, role) +{ + Q_ASSERT(toolButton()); +} + +/*! Returns the button. */ +QToolButton *QAccessibleToolButton::toolButton() const +{ + return qobject_cast(object()); +} + +/*! + Returns \c 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 +} + +QAccessible::State QAccessibleToolButton::state() const +{ + QAccessible::State st = QAccessibleButton::state(); + if (toolButton()->autoRaise()) + st.hotTracked = true; +#ifndef QT_NO_MENU + if (toolButton()->menu()) + st.hasPopup = true; +#endif + return st; +} + +int QAccessibleToolButton::childCount() const +{ + return isSplitButton() ? 1 : 0; +} + +QAccessibleInterface *QAccessibleToolButton::child(int index) const +{ +#ifndef QT_NO_MENU + if (index == 0 && toolButton()->menu()) + { + return QAccessible::queryAccessibleInterface(toolButton()->menu()); + } +#endif + return 0; +} + +/*! + \internal + + Returns the button's text label, depending on the text \a t, and + the \a child. +*/ +QString QAccessibleToolButton::text(QAccessible::Text t) const +{ + QString str; + switch (t) { + case QAccessible::Name: + str = toolButton()->accessibleName(); + if (str.isEmpty()) + str = toolButton()->text(); + break; + default: + break; + } + if (str.isEmpty()) + str = QAccessibleButton::text(t); + return qt_accStripAmp(str); +} + +/* + The three different tool button types can have the following actions: +| DelayedPopup | ShowMenuAction + (PressedAction || CheckedAction) | +| MenuButtonPopup | ShowMenuAction + (PressedAction || CheckedAction) | +| InstantPopup | ShowMenuAction | +*/ +QStringList QAccessibleToolButton::actionNames() const +{ + QStringList names; + if (widget()->isEnabled()) { + if (toolButton()->menu()) + names << showMenuAction(); + if (toolButton()->popupMode() != QToolButton::InstantPopup) + names << QAccessibleButton::actionNames(); + } + return names; +} + +void QAccessibleToolButton::doAction(const QString &actionName) +{ + if (!widget()->isEnabled()) + return; + + if (actionName == pressAction()) { + button()->click(); + } else if (actionName == showMenuAction()) { + if (toolButton()->popupMode() != QToolButton::InstantPopup) { + toolButton()->setDown(true); +#ifndef QT_NO_MENU + toolButton()->showMenu(); +#endif + } + } else { + QAccessibleButton::doAction(actionName); + } + +} + +#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 QAccessibleWidget constructor. +*/ +QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role) +: QAccessibleWidget(w, role) +{ +} + +QAccessible::Role QAccessibleDisplay::role() const +{ + QLabel *l = qobject_cast(object()); + if (l) { + if (l->pixmap()) + return QAccessible::Graphic; +#ifndef QT_NO_PICTURE + if (l->picture()) + return QAccessible::Graphic; +#endif +#ifndef QT_NO_MOVIE + if (l->movie()) + return QAccessible::Animation; +#endif +#ifndef QT_NO_PROGRESSBAR + } else if (qobject_cast(object())) { + return QAccessible::ProgressBar; +#endif + } else if (qobject_cast(object())) { + return QAccessible::StatusBar; + } + return QAccessibleWidget::role(); +} + +QString QAccessibleDisplay::text(QAccessible::Text t) const +{ + QString str; + switch (t) { + case QAccessible::Name: + str = widget()->accessibleName(); + if (str.isEmpty()) { + if (qobject_cast(object())) { + QLabel *label = qobject_cast(object()); + str = label->text(); + if (label->textFormat() == Qt::RichText + || (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(str))) { + QTextDocument doc; + doc.setHtml(str); + str = doc.toPlainText(); + } +#ifndef QT_NO_LCDNUMBER + } else if (qobject_cast(object())) { + QLCDNumber *l = qobject_cast(object()); + if (l->digitCount()) + str = QString::number(l->value()); + else + str = QString::number(l->intValue()); +#endif + } else if (qobject_cast(object())) { + return qobject_cast(object())->currentMessage(); + } + } + break; + case QAccessible::Value: +#ifndef QT_NO_PROGRESSBAR + if (qobject_cast(object())) + str = QString::number(qobject_cast(object())->value()); +#endif + break; + default: + break; + } + if (str.isEmpty()) + str = QAccessibleWidget::text(t); + return qt_accStripAmp(str); +} + +/*! \reimp */ +QVector > +QAccessibleDisplay::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const +{ + QVector > rels = QAccessibleWidget::relations(match); + if (match & QAccessible::Labelled) { + QVarLengthArray relatedObjects; + +#ifndef QT_NO_SHORTCUT + if (QLabel *label = qobject_cast(object())) { + relatedObjects.append(label->buddy()); + } +#endif + for (int i = 0; i < relatedObjects.count(); ++i) { + const QAccessible::Relation rel = QAccessible::Labelled; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i)); + if (iface) + rels.append(qMakePair(iface, rel)); + } + } + return rels; +} + +void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::ImageInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} + +/*! \internal */ +QString QAccessibleDisplay::imageDescription() const +{ +#ifndef QT_NO_TOOLTIP + return widget()->toolTip(); +#else + return QString::null; +#endif +} + +/*! \internal */ +QSize QAccessibleDisplay::imageSize() const +{ + QLabel *label = qobject_cast(widget()); + if (!label) + return QSize(); + const QPixmap *pixmap = label->pixmap(); + if (!pixmap) + return QSize(); + return pixmap->size(); +} + +/*! \internal */ +QPoint QAccessibleDisplay::imagePosition() const +{ + QLabel *label = qobject_cast(widget()); + if (!label) + return QPoint(); + const QPixmap *pixmap = label->pixmap(); + if (!pixmap) + return QPoint(); + + return QPoint(label->mapToGlobal(label->pos())); +} + +#ifndef QT_NO_GROUPBOX +QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w) +: QAccessibleWidget(w) +{ +} + +QGroupBox* QAccessibleGroupBox::groupBox() const +{ + return static_cast(widget()); +} + +QString QAccessibleGroupBox::text(QAccessible::Text t) const +{ + QString txt = QAccessibleWidget::text(t); + + if (txt.isEmpty()) { + switch (t) { + case QAccessible::Name: + txt = qt_accStripAmp(groupBox()->title()); + break; + case QAccessible::Description: + txt = qt_accStripAmp(groupBox()->toolTip()); + break; + default: + break; + } + } + + return txt; +} + +QAccessible::State QAccessibleGroupBox::state() const +{ + QAccessible::State st = QAccessibleWidget::state(); + st.checkable = groupBox()->isCheckable(); + st.checked = groupBox()->isChecked(); + return st; +} + +QAccessible::Role QAccessibleGroupBox::role() const +{ + return groupBox()->isCheckable() ? QAccessible::CheckBox : QAccessible::Grouping; +} + +QVector > +QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const +{ + QVector > rels = QAccessibleWidget::relations(match); + + if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) { + const QList kids = childWidgets(widget()); + for (int i = 0; i < kids.count(); ++i) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kids.at(i)); + if (iface) + rels.append(qMakePair(iface, QAccessible::Relation(QAccessible::Labelled))); + } + } + return rels; +} + +QStringList QAccessibleGroupBox::actionNames() const +{ + QStringList actions = QAccessibleWidget::actionNames(); + + if (groupBox()->isCheckable()) { + actions.prepend(QAccessibleActionInterface::toggleAction()); + } + return actions; +} + +void QAccessibleGroupBox::doAction(const QString &actionName) +{ + if (actionName == QAccessibleActionInterface::toggleAction()) + groupBox()->setChecked(!groupBox()->isChecked()); +} + +QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const +{ + return QStringList(); +} + +#endif + +#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 QAccessibleWidget constructor. +*/ +QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name) +: QAccessibleWidget(w, QAccessible::EditableText, name) +{ + addControllingSignal(QLatin1String("textChanged(const QString&)")); + addControllingSignal(QLatin1String("returnPressed()")); +} + +/*! Returns the line edit. */ +QLineEdit *QAccessibleLineEdit::lineEdit() const +{ + return qobject_cast(object()); +} + +QString QAccessibleLineEdit::text(QAccessible::Text t) const +{ + QString str; + switch (t) { + case QAccessible::Value: + if (lineEdit()->echoMode() == QLineEdit::Normal) + str = lineEdit()->text(); + break; + default: + break; + } + if (str.isEmpty()) + str = QAccessibleWidget::text(t); + return qt_accStripAmp(str); +} + +void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text) +{ + if (t != QAccessible::Value) { + QAccessibleWidget::setText(t, text); + return; + } + + QString newText = text; + if (lineEdit()->validator()) { + int pos = 0; + if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable) + return; + } + lineEdit()->setText(newText); +} + +QAccessible::State QAccessibleLineEdit::state() const +{ + QAccessible::State state = QAccessibleWidget::state(); + + QLineEdit *l = lineEdit(); + if (l->isReadOnly()) + state.readOnly = true; + else + state.editable = true; + + if (l->echoMode() != QLineEdit::Normal) + state.passwordEdit = true; + state.selectable = true; + if (l->hasSelectedText()) + state.selected = true; + + if (l->contextMenuPolicy() != Qt::NoContextMenu + && l->contextMenuPolicy() != Qt::PreventContextMenu) + state.hasPopup = true; + + return state; +} + +void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::TextInterface) + return static_cast(this); + if (t == QAccessible::EditableTextInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} + +void QAccessibleLineEdit::addSelection(int startOffset, int endOffset) +{ + setSelection(0, startOffset, endOffset); +} + +QString QAccessibleLineEdit::attributes(int offset, int *startOffset, int *endOffset) const +{ + // QLineEdit doesn't have text attributes + *startOffset = *endOffset = offset; + return QString(); +} + +int QAccessibleLineEdit::cursorPosition() const +{ + return lineEdit()->cursorPosition(); +} + +QRect QAccessibleLineEdit::characterRect(int offset) const +{ + int x = lineEdit()->d_func()->control->cursorToX(offset); + int y; + lineEdit()->getTextMargins(0, &y, 0, 0); + QFontMetrics fm(lineEdit()->font()); + const QString ch = text(offset, offset + 1); + if (ch.isEmpty()) + return QRect(); + int w = fm.width(ch); + int h = fm.height(); + QRect r(x, y, w, h); + r.moveTo(lineEdit()->mapToGlobal(r.topLeft())); + return r; +} + +int QAccessibleLineEdit::selectionCount() const +{ + return lineEdit()->hasSelectedText() ? 1 : 0; +} + +int QAccessibleLineEdit::offsetAtPoint(const QPoint &point) const +{ + QPoint p = lineEdit()->mapFromGlobal(point); + + return lineEdit()->cursorPositionAt(p); +} + +void QAccessibleLineEdit::selection(int selectionIndex, int *startOffset, int *endOffset) const +{ + *startOffset = *endOffset = 0; + if (selectionIndex != 0) + return; + + *startOffset = lineEdit()->selectionStart(); + *endOffset = *startOffset + lineEdit()->selectedText().count(); +} + +QString QAccessibleLineEdit::text(int startOffset, int endOffset) const +{ + if (startOffset > endOffset) + return QString(); + + if (lineEdit()->echoMode() != QLineEdit::Normal) + return QString(); + + return lineEdit()->text().mid(startOffset, endOffset - startOffset); +} + +QString QAccessibleLineEdit::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + if (lineEdit()->echoMode() != QLineEdit::Normal) { + *startOffset = *endOffset = -1; + return QString(); + } + return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset); +} + +QString QAccessibleLineEdit::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + if (lineEdit()->echoMode() != QLineEdit::Normal) { + *startOffset = *endOffset = -1; + return QString(); + } + return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset); +} + +QString QAccessibleLineEdit::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const +{ + if (lineEdit()->echoMode() != QLineEdit::Normal) { + *startOffset = *endOffset = -1; + return QString(); + } + return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset); +} + +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() const +{ + return lineEdit()->text().count(); +} + +void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex) +{ + lineEdit()->setCursorPosition(endIndex); + lineEdit()->setCursorPosition(startIndex); +} + +void QAccessibleLineEdit::deleteText(int startOffset, int endOffset) +{ + lineEdit()->setText(lineEdit()->text().remove(startOffset, endOffset - startOffset)); +} + +void QAccessibleLineEdit::insertText(int offset, const QString &text) +{ + lineEdit()->setText(lineEdit()->text().insert(offset, text)); +} + +void QAccessibleLineEdit::replaceText(int startOffset, int endOffset, const QString &text) +{ + lineEdit()->setText(lineEdit()->text().replace(startOffset, endOffset - startOffset, text)); +} + +#endif // QT_NO_LINEEDIT + +#ifndef QT_NO_PROGRESSBAR +QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o) + : QAccessibleDisplay(o) +{ + Q_ASSERT(progressBar()); +} + +void *QAccessibleProgressBar::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::ValueInterface) + return static_cast(this); + return QAccessibleDisplay::interface_cast(t); +} + +QVariant QAccessibleProgressBar::currentValue() const +{ + return progressBar()->value(); +} + +QVariant QAccessibleProgressBar::maximumValue() const +{ + return progressBar()->maximum(); +} + +QVariant QAccessibleProgressBar::minimumValue() const +{ + return progressBar()->minimum(); +} + +QVariant QAccessibleProgressBar::minimumStepSize() const +{ + // This is arbitrary since any value between min and max is valid. + // Some screen readers (orca use it to calculate how many digits to display though, + // so it makes sense to return a "sensible" value. Providing 100 increments seems ok. + return (progressBar()->maximum() - progressBar()->minimum()) / 100.0; +} + +QProgressBar *QAccessibleProgressBar::progressBar() const +{ + return qobject_cast(object()); +} +#endif + + +QAccessibleWindowContainer::QAccessibleWindowContainer(QWidget *w) + : QAccessibleWidget(w) +{ +} + +int QAccessibleWindowContainer::childCount() const +{ + if (container()->containedWindow()) + return 1; + return 0; +} + +int QAccessibleWindowContainer::indexOfChild(const QAccessibleInterface *child) const +{ + if (child->object() == container()->containedWindow()) + return 0; + return -1; +} + +QAccessibleInterface *QAccessibleWindowContainer::child(int i) const +{ + if (i == 0) + return QAccessible::queryAccessibleInterface(container()->containedWindow()); + return 0; +} + +QWindowContainer *QAccessibleWindowContainer::container() const +{ + return static_cast(widget()); +} + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE diff --git a/src/widgets/accessible/simplewidgets.h b/src/widgets/accessible/simplewidgets.h new file mode 100644 index 0000000000..be19d8324f --- /dev/null +++ b/src/widgets/accessible/simplewidgets.h @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SIMPLEWIDGETS_H +#define SIMPLEWIDGETS_H + +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +class QAbstractButton; +class QLineEdit; +class QToolButton; +class QGroupBox; +class QProgressBar; + +class QAccessibleButton : public QAccessibleWidget +{ + Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) +public: + QAccessibleButton(QWidget *w, QAccessible::Role r); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + +protected: + QAbstractButton *button() const; +}; + +#ifndef QT_NO_TOOLBUTTON +class QAccessibleToolButton : public QAccessibleButton +{ +public: + QAccessibleToolButton(QWidget *w, QAccessible::Role role); + + QAccessible::State state() const Q_DECL_OVERRIDE; + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + // QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + +protected: + QToolButton *toolButton() const; + + bool isSplitButton() const; +}; +#endif // QT_NO_TOOLBUTTON + +class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface +{ +public: + explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + + QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleImageInterface + QString imageDescription() const Q_DECL_OVERRIDE; + QSize imageSize() const Q_DECL_OVERRIDE; + QPoint imagePosition() const Q_DECL_OVERRIDE; +}; + +#ifndef QT_NO_GROUPBOX +class QAccessibleGroupBox : public QAccessibleWidget +{ +public: + explicit QAccessibleGroupBox(QWidget *w); + + QAccessible::State state() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; + + //QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &) const Q_DECL_OVERRIDE; + +private: + QGroupBox *groupBox() const; +}; +#endif + +#ifndef QT_NO_LINEEDIT +class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface +{ +public: + explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString()); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int cursorPosition() const Q_DECL_OVERRIDE; + QRect characterRect(int offset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; + QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; + int characterCount() const Q_DECL_OVERRIDE; + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + // QAccessibleEditableTextInterface + void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; + void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; +protected: + QLineEdit *lineEdit() const; +}; +#endif // QT_NO_LINEEDIT + +#ifndef QT_NO_PROGRESSBAR +class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface +{ +public: + explicit QAccessibleProgressBar(QWidget *o); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleValueInterface + QVariant currentValue() const Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &) Q_DECL_OVERRIDE {} + +protected: + QProgressBar *progressBar() const; +}; +#endif + +class QWindowContainer; +class QAccessibleWindowContainer : public QAccessibleWidget +{ +public: + QAccessibleWindowContainer(QWidget *w); + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int i) const Q_DECL_OVERRIDE; + +private: + QWindowContainer *container() const; +}; + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // SIMPLEWIDGETS_H diff --git a/src/widgets/accessible/widgets.pro b/src/widgets/accessible/widgets.pro new file mode 100644 index 0000000000..aff60d9781 --- /dev/null +++ b/src/widgets/accessible/widgets.pro @@ -0,0 +1,26 @@ +TARGET = qtaccessiblewidgets + +PLUGIN_TYPE = accessible +PLUGIN_CLASS_NAME = AccessibleFactory +load(qt_plugin) + +QT += core-private gui-private widgets-private + +QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)" + +SOURCES += main.cpp \ + simplewidgets.cpp \ + rangecontrols.cpp \ + complexwidgets.cpp \ + qaccessiblewidgets.cpp \ + qaccessiblemenu.cpp \ + itemviews.cpp + +HEADERS += qaccessiblewidgets.h \ + simplewidgets.h \ + rangecontrols.h \ + complexwidgets.h \ + qaccessiblemenu.h \ + itemviews.h + + diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 9e221c1bf4..c053fdfb22 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -77,6 +77,7 @@ #endif #include "private/qkeymapper_p.h" +#include "private/qaccessiblewidgetfactory_p.h" #include #include @@ -557,6 +558,11 @@ void QApplicationPrivate::construct() qt_gui_eval_init(application_type); #endif +#ifndef QT_NO_ACCESSIBILITY + // factory for accessible interfaces for widgets shipped with Qt + QAccessible::installFactory(&qAccessibleFactory); +#endif + #ifndef QT_NO_LIBRARY if(load_testability) { QLibrary testLib(QLatin1String("qttestability")); diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index 0b289c75ae..c2cf4b7dfe 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -8,9 +8,6 @@ DEFINES += QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused -MODULE_PLUGIN_TYPES += \ - accessible/libqtaccessiblewidgets.so - QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf load(qt_module) -- cgit v1.2.3