13#include <private/qwidget_p.h>
15#if QT_CONFIG(accessibility)
17#include <QtGui/private/qaccessiblehelper_p.h>
23QString qt_accHotKey(
const QString &text);
25QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action)
27 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action);
29 iface =
new QAccessibleMenuItem(menu, action);
30 QAccessible::registerAccessibleInterface(iface);
35QAccessibleMenu::QAccessibleMenu(QWidget *w)
36: QAccessibleWidgetV2(w)
41QMenu *QAccessibleMenu::menu()
const
43 return qobject_cast<QMenu*>(object());
46int QAccessibleMenu::childCount()
const
48 return menu()->actions().size();
51QAccessibleInterface *QAccessibleMenu::childAt(
int x,
int y)
const
53 QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
54 if (act && act->isSeparator())
56 return act ? getOrCreateMenu(menu(), act) :
nullptr;
59QString QAccessibleMenu::text(QAccessible::Text t)
const
61 QString tx = QAccessibleWidgetV2::text(t);
65 if (t == QAccessible::Name)
66 return menu()->windowTitle();
70QAccessible::Role QAccessibleMenu::role()
const
72 return QAccessible::PopupMenu;
75QAccessibleInterface *QAccessibleMenu::child(
int index)
const
77 if (index < childCount())
78 return getOrCreateMenu(menu(), menu()->actions().at(index));
82QAccessibleInterface *QAccessibleMenu::parent()
const
84 if (QAction *menuAction = menu()->menuAction()) {
85 QList<QObject *> parentCandidates;
86 const QList<QObject *> associatedObjects = menuAction->associatedObjects();
87 parentCandidates.reserve(associatedObjects.size() + 1);
88 parentCandidates << menu()->parentWidget() << associatedObjects;
89 for (QObject *object : std::as_const(parentCandidates)) {
90 if (qobject_cast<QMenu*>(object)
92 || qobject_cast<QMenuBar*>(object)
95 QWidget *widget =
static_cast<QWidget*>(object);
96 if (widget->actions().indexOf(menuAction) != -1)
97 return getOrCreateMenu(widget, menuAction);
101 return QAccessibleWidgetV2::parent();
104int QAccessibleMenu::indexOfChild(
const QAccessibleInterface *child)
const
106 QAccessible::Role r = child->role();
107 if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) {
108 return menu()->actions().indexOf(qobject_cast<QAction*>(child->object()));
113#if QT_CONFIG(menubar)
114QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
115 : QAccessibleWidgetV2(w, QAccessible::MenuBar)
120QMenuBar *QAccessibleMenuBar::menuBar()
const
122 return qobject_cast<QMenuBar*>(object());
125int QAccessibleMenuBar::childCount()
const
127 return menuBar()->actions().size();
130QAccessibleInterface *QAccessibleMenuBar::child(
int index)
const
132 if (index < childCount()) {
133 return getOrCreateMenu(menuBar(), menuBar()->actions().at(index));
138int QAccessibleMenuBar::indexOfChild(
const QAccessibleInterface *child)
const
140 QAccessible::Role r = child->role();
141 if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) {
142 return menuBar()->actions().indexOf(qobject_cast<QAction*>(child->object()));
149QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action)
150: m_action(action), m_owner(owner)
154QAccessibleMenuItem::~QAccessibleMenuItem()
157QAccessibleInterface *QAccessibleMenuItem::childAt(
int x,
int y )
const
159 for (
int i = childCount() - 1; i >= 0; --i) {
160 QAccessibleInterface *childInterface = child(i);
161 if (childInterface->rect().contains(x,y)) {
162 return childInterface;
168int QAccessibleMenuItem::childCount()
const
170 return m_action->menu() ? 1 : 0;
173int QAccessibleMenuItem::indexOfChild(
const QAccessibleInterface * child)
const
175 if (child && child->role() == QAccessible::PopupMenu && child->object() == m_action->menu())
180bool QAccessibleMenuItem::isValid()
const
182 return m_action && m_owner;
185QAccessibleInterface *QAccessibleMenuItem::parent()
const
187 return QAccessible::queryAccessibleInterface(owner());
190QAccessibleInterface *QAccessibleMenuItem::child(
int index)
const
192 if (index == 0 && action()->menu())
193 return QAccessible::queryAccessibleInterface(action()->menu());
197void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t)
199 if (t == QAccessible::ActionInterface)
200 return static_cast<QAccessibleActionInterface*>(
this);
204QObject *QAccessibleMenuItem::object()
const
210QWindow *QAccessibleMenuItem::window()
const
212 return m_owner.isNull()
214 : qt_widget_private(m_owner.data())->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
217QRect QAccessibleMenuItem::rect()
const
220 QWidget *own = owner();
221#if QT_CONFIG(menubar)
222 if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
223 rect = menuBar->actionGeometry(m_action);
224 QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
225 rect = rect.translated(globalPos);
228 if (QMenu *menu = qobject_cast<QMenu*>(own)) {
229 rect = menu->actionGeometry(m_action);
230 QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
231 rect = rect.translated(globalPos);
236QAccessible::Role QAccessibleMenuItem::role()
const
238 return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem;
241void QAccessibleMenuItem::setText(QAccessible::Text ,
const QString & )
245QAccessible::State QAccessibleMenuItem::state()
const
247 QAccessible::State s;
248 QWidget *own = owner();
250 if (own && (own->testAttribute(Qt::WA_WState_Visible) ==
false || m_action->isVisible() ==
false)) {
254 if (QMenu *menu = qobject_cast<QMenu*>(own)) {
255 if (menu->activeAction() == m_action)
257#if QT_CONFIG(menubar)
258 }
else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
259 if (menuBar->activeAction() == m_action)
263 if (own && own->style()->styleHint(QStyle::SH_Menu_MouseTracking,
nullptr, own))
265 if (m_action->isSeparator() || !m_action->isEnabled())
267 if (m_action->isChecked())
269 if (m_action->isCheckable())
275QString QAccessibleMenuItem::text(QAccessible::Text t)
const
279 case QAccessible::Name:
280 str = qt_accStripAmp(m_action->text());
282 case QAccessible::Accelerator: {
283#ifndef QT_NO_SHORTCUT
284 QKeySequence key = m_action->shortcut();
285 if (!key.isEmpty()) {
286 str = key.toString();
290 str = qt_accHotKey(m_action->text());
300QStringList QAccessibleMenuItem::actionNames()
const
303 if (!m_action || m_action->isSeparator())
306 if (m_action->menu()) {
307 actions << showMenuAction();
309 actions << pressAction();
314void QAccessibleMenuItem::doAction(
const QString &actionName)
316 if (!m_action->isEnabled())
319 if (actionName == pressAction()) {
321 }
else if (actionName == showMenuAction()) {
322#if QT_CONFIG(menubar)
323 if (QMenuBar *bar = qobject_cast<QMenuBar*>(owner())) {
324 if (m_action->menu() && m_action->menu()->isVisible()) {
325 m_action->menu()->hide();
327 bar->setActiveAction(m_action);
331 if (QMenu *menu = qobject_cast<QMenu*>(owner())){
332 if (m_action->menu() && m_action->menu()->isVisible()) {
333 m_action->menu()->hide();
335 menu->setActiveAction(m_action);
341QStringList QAccessibleMenuItem::keyBindingsForAction(
const QString &)
const
343 return QStringList();
347QAction *QAccessibleMenuItem::action()
const
352QWidget *QAccessibleMenuItem::owner()
const