14#include <private/qwidget_p.h>
16#if QT_CONFIG(accessibility)
18#include <QtGui/private/qaccessiblehelper_p.h>
24QString qt_accHotKey(
const QString &text);
26QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action)
28 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action);
30 iface =
new QAccessibleMenuItem(menu, action);
31 QAccessible::registerAccessibleInterface(iface);
36QAccessibleMenu::QAccessibleMenu(QWidget *w)
37: QAccessibleWidgetV2(w)
42QMenu *QAccessibleMenu::menu()
const
44 return qobject_cast<QMenu*>(object());
47int QAccessibleMenu::childCount()
const
49 return menu()->actions().size();
52QAccessibleInterface *QAccessibleMenu::childAt(
int x,
int y)
const
54 QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
55 if (act && act->isSeparator())
57 return act ? getOrCreateMenu(menu(), act) :
nullptr;
60QString QAccessibleMenu::text(QAccessible::Text t)
const
62 QString tx = QAccessibleWidgetV2::text(t);
66 if (t == QAccessible::Name)
67 return menu()->windowTitle();
71QAccessible::Role QAccessibleMenu::role()
const
73 return QAccessible::PopupMenu;
76QAccessibleInterface *QAccessibleMenu::child(
int index)
const
78 if (index < childCount())
79 return getOrCreateMenu(menu(), menu()->actions().at(index));
83QAccessibleInterface *QAccessibleMenu::parent()
const
85 if (QAction *menuAction = menu()->menuAction()) {
86 QList<QObject *> parentCandidates;
87 const QList<QObject *> associatedObjects = menuAction->associatedObjects();
88 parentCandidates.reserve(associatedObjects.size() + 1);
89 parentCandidates << menu()->parentWidget() << associatedObjects;
90 for (QObject *object : std::as_const(parentCandidates)) {
91 if (qobject_cast<QMenu*>(object)
93 || qobject_cast<QMenuBar*>(object)
96 QWidget *widget =
static_cast<QWidget*>(object);
97 if (widget->actions().indexOf(menuAction) != -1)
98 return getOrCreateMenu(widget, menuAction);
102 return QAccessibleWidgetV2::parent();
105int QAccessibleMenu::indexOfChild(
const QAccessibleInterface *child)
const
107 QAccessible::Role r = child->role();
108 if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) {
109 return menu()->actions().indexOf(qobject_cast<QAction*>(child->object()));
114#if QT_CONFIG(menubar)
115QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
116 : QAccessibleWidgetV2(w, QAccessible::MenuBar)
121QMenuBar *QAccessibleMenuBar::menuBar()
const
123 return qobject_cast<QMenuBar*>(object());
126int QAccessibleMenuBar::childCount()
const
128 return menuBar()->actions().size();
131QAccessibleInterface *QAccessibleMenuBar::child(
int index)
const
133 if (index < childCount()) {
134 return getOrCreateMenu(menuBar(), menuBar()->actions().at(index));
139int QAccessibleMenuBar::indexOfChild(
const QAccessibleInterface *child)
const
141 QAccessible::Role r = child->role();
142 if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) {
143 return menuBar()->actions().indexOf(qobject_cast<QAction*>(child->object()));
151
152
153
154
155QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action)
156: m_action(action), m_owner(owner)
160QAccessibleMenuItem::~QAccessibleMenuItem()
163QAccessibleInterface *QAccessibleMenuItem::childAt(
int x,
int y )
const
165 for (
int i = childCount() - 1; i >= 0; --i) {
166 QAccessibleInterface *childInterface = child(i);
167 if (childInterface->rect().contains(x,y)) {
168 return childInterface;
174int QAccessibleMenuItem::childCount()
const
176 return m_action->menu() ? 1 : 0;
179int QAccessibleMenuItem::indexOfChild(
const QAccessibleInterface * child)
const
181 if (child && child->role() == QAccessible::PopupMenu && child->object() == m_action->menu())
186bool QAccessibleMenuItem::isValid()
const
188 return m_action && m_owner;
191QAccessibleInterface *QAccessibleMenuItem::parent()
const
193 return QAccessible::queryAccessibleInterface(owner());
196QAccessibleInterface *QAccessibleMenuItem::child(
int index)
const
198 if (index == 0 && action()->menu())
199 return QAccessible::queryAccessibleInterface(action()->menu());
203void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t)
205 if (t == QAccessible::ActionInterface)
206 return static_cast<QAccessibleActionInterface*>(
this);
208 if (t == QAccessible::AttributesInterface && m_action && !m_action->isSeparator())
209 return static_cast<QAccessibleAttributesInterface *>(
this);
213QList<QAccessible::Attribute> QAccessibleMenuItem::attributeKeys()
const
215 return { QAccessible::Attribute::PositionInSet, QAccessible::Attribute::SizeOfSet };
218QVariant QAccessibleMenuItem::attributeValue(QAccessible::Attribute key)
const
220 if (key != QAccessible::Attribute::PositionInSet && key != QAccessible::Attribute::SizeOfSet)
226 const auto actions = owner()->actions();
227 for (QAction *action : actions) {
228 if (action->isSeparator() || !action->isVisible())
231 if (key == QAccessible::Attribute::PositionInSet && action == m_action)
234 return (key == QAccessible::Attribute::SizeOfSet) ? QVariant(size) : QVariant();
237QObject *QAccessibleMenuItem::object()
const
243QWindow *QAccessibleMenuItem::window()
const
245 return m_owner.isNull()
247 : qt_widget_private(m_owner.data())->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
250QRect QAccessibleMenuItem::rect()
const
253 QWidget *own = owner();
254#if QT_CONFIG(menubar)
255 if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
256 rect = menuBar->actionGeometry(m_action);
257 QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
258 rect = rect.translated(globalPos);
261 if (QMenu *menu = qobject_cast<QMenu*>(own)) {
262 rect = menu->actionGeometry(m_action);
263 QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
264 rect = rect.translated(globalPos);
269QAccessible::Role QAccessibleMenuItem::role()
const
271 return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem;
274void QAccessibleMenuItem::setText(QAccessible::Text ,
const QString & )
278QAccessible::State QAccessibleMenuItem::state()
const
280 QAccessible::State s;
281 QWidget *own = owner();
283 if (own && (own->testAttribute(Qt::WA_WState_Visible) ==
false || m_action->isVisible() ==
false)) {
287 if (QMenu *menu = qobject_cast<QMenu*>(own)) {
288 if (menu->activeAction() == m_action)
290#if QT_CONFIG(menubar)
291 }
else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
292 if (menuBar->activeAction() == m_action)
296 if (own && own->style()->styleHint(QStyle::SH_Menu_MouseTracking,
nullptr, own))
298 if (m_action->isSeparator() || !m_action->isEnabled())
300 if (m_action->isChecked())
302 if (m_action->isCheckable())
308QString QAccessibleMenuItem::text(QAccessible::Text t)
const
312 case QAccessible::Name:
313 str = qt_accStripAmp(m_action->text());
315 case QAccessible::Accelerator: {
316#ifndef QT_NO_SHORTCUT
317 QKeySequence key = m_action->shortcut();
318 if (!key.isEmpty()) {
319 str = key.toString();
323 str = qt_accHotKey(m_action->text());
333QStringList QAccessibleMenuItem::actionNames()
const
336 if (!m_action || m_action->isSeparator())
339 if (m_action->menu()) {
340 actions << showMenuAction();
342 actions << pressAction();
347void QAccessibleMenuItem::doAction(
const QString &actionName)
349 if (!m_action->isEnabled())
352 if (actionName == pressAction()) {
354 }
else if (actionName == showMenuAction()) {
355#if QT_CONFIG(menubar)
356 if (QMenuBar *bar = qobject_cast<QMenuBar*>(owner())) {
357 if (m_action->menu() && m_action->menu()->isVisible()) {
358 m_action->menu()->hide();
360 bar->setActiveAction(m_action);
364 if (QMenu *menu = qobject_cast<QMenu*>(owner())){
365 if (m_action->menu() && m_action->menu()->isVisible()) {
366 m_action->menu()->hide();
368 menu->setActiveAction(m_action);
374QStringList QAccessibleMenuItem::keyBindingsForAction(
const QString &)
const
376 return QStringList();
380QAction *QAccessibleMenuItem::action()
const
385QWidget *QAccessibleMenuItem::owner()
const