diff options
Diffstat (limited to 'src/widgets/accessible/qaccessiblemenu.cpp')
-rw-r--r-- | src/widgets/accessible/qaccessiblemenu.cpp | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp new file mode 100644 index 0000000000..f47980d786 --- /dev/null +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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 <qmenu.h> +#include <qmenubar.h> +#include <QtWidgets/QAction> +#include <qstyle.h> + +#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<QMenu*>(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<QWidget *> parentCandidates; + parentCandidates << menu()->parentWidget(); + parentCandidates << menuAction->associatedWidgets(); + foreach (QWidget *w, parentCandidates) { + if (qobject_cast<QMenu*>(w) || qobject_cast<QMenuBar*>(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<QAction*>(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<QMenuBar*>(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<QAction*>(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<QAccessibleActionInterface*>(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<QMenuBar*>(own)) { + rect = menuBar->actionGeometry(m_action); + QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0)); + rect = rect.translated(globalPos); + } else +#endif // QT_NO_MENUBAR + if (QMenu *menu = qobject_cast<QMenu*>(own)) { + rect = menu->actionGeometry(m_action); + QPoint globalPos = menu->mapToGlobal(QPoint(0,0)); + rect = rect.translated(globalPos); + } + 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<QMenu*>(own)) { + if (menu->activeAction() == m_action) + s.focused = true; +#ifndef QT_NO_MENUBAR + } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(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<QMenuBar*>(owner())) { + if (m_action->menu() && m_action->menu()->isVisible()) { + m_action->menu()->hide(); + } else { + bar->setActiveAction(m_action); + } + } else if (QMenu *menu = qobject_cast<QMenu*>(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 + |