Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qaccessiblemenu.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qaccessiblemenu_p.h"
5
6#if QT_CONFIG(menu)
7#include <qmenu.h>
8#endif
9#if QT_CONFIG(menubar)
10#include <qmenubar.h>
11#endif
12#include <qstyle.h>
13#include <private/qwidget_p.h>
14
15#if QT_CONFIG(accessibility)
16
18
19#if QT_CONFIG(menu)
20
21QString qt_accStripAmp(const QString &text);
22QString qt_accHotKey(const QString &text);
23
24QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action)
25{
26 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action);
27 if (!iface) {
28 iface = new QAccessibleMenuItem(menu, action);
29 QAccessible::registerAccessibleInterface(iface);
30 }
31 return iface;
32}
33
34QAccessibleMenu::QAccessibleMenu(QWidget *w)
35: QAccessibleWidget(w)
36{
37 Q_ASSERT(menu());
38}
39
40QMenu *QAccessibleMenu::menu() const
41{
42 return qobject_cast<QMenu*>(object());
43}
44
45int QAccessibleMenu::childCount() const
46{
47 return menu()->actions().size();
48}
49
50QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const
51{
52 QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
53 if (act && act->isSeparator())
54 act = nullptr;
55 return act ? getOrCreateMenu(menu(), act) : nullptr;
56}
57
58QString QAccessibleMenu::text(QAccessible::Text t) const
59{
60 QString tx = QAccessibleWidget::text(t);
61 if (!tx.isEmpty())
62 return tx;
63
64 if (t == QAccessible::Name)
65 return menu()->windowTitle();
66 return tx;
67}
68
69QAccessible::Role QAccessibleMenu::role() const
70{
71 return QAccessible::PopupMenu;
72}
73
74QAccessibleInterface *QAccessibleMenu::child(int index) const
75{
76 if (index < childCount())
77 return getOrCreateMenu(menu(), menu()->actions().at(index));
78 return nullptr;
79}
80
81QAccessibleInterface *QAccessibleMenu::parent() const
82{
83 if (QAction *menuAction = menu()->menuAction()) {
84 QList<QObject *> parentCandidates;
85 const QList<QObject *> associatedObjects = menuAction->associatedObjects();
86 parentCandidates.reserve(associatedObjects.size() + 1);
87 parentCandidates << menu()->parentWidget() << associatedObjects;
88 for (QObject *object : std::as_const(parentCandidates)) {
89 if (qobject_cast<QMenu*>(object)
90#if QT_CONFIG(menubar)
91 || qobject_cast<QMenuBar*>(object)
92#endif
93 ) {
94 QWidget *widget = static_cast<QWidget*>(object);
95 if (widget->actions().indexOf(menuAction) != -1)
96 return getOrCreateMenu(widget, menuAction);
97 }
98 }
99 }
100 return QAccessibleWidget::parent();
101}
102
103int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const
104{
105 QAccessible::Role r = child->role();
106 if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) {
107 return menu()->actions().indexOf(qobject_cast<QAction*>(child->object()));
108 }
109 return -1;
110}
111
112#if QT_CONFIG(menubar)
113QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
114 : QAccessibleWidget(w, QAccessible::MenuBar)
115{
116 Q_ASSERT(menuBar());
117}
118
119QMenuBar *QAccessibleMenuBar::menuBar() const
120{
121 return qobject_cast<QMenuBar*>(object());
122}
123
124int QAccessibleMenuBar::childCount() const
125{
126 return menuBar()->actions().size();
127}
128
129QAccessibleInterface *QAccessibleMenuBar::child(int index) const
130{
131 if (index < childCount()) {
132 return getOrCreateMenu(menuBar(), menuBar()->actions().at(index));
133 }
134 return nullptr;
135}
136
137int QAccessibleMenuBar::indexOfChild(const QAccessibleInterface *child) const
138{
139 QAccessible::Role r = child->role();
140 if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) {
141 return menuBar()->actions().indexOf(qobject_cast<QAction*>(child->object()));
142 }
143 return -1;
144}
145
146#endif // QT_CONFIG(menubar)
147
148QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action)
149: m_action(action), m_owner(owner)
150{
151}
152
153QAccessibleMenuItem::~QAccessibleMenuItem()
154{}
155
156QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const
157{
158 for (int i = childCount() - 1; i >= 0; --i) {
159 QAccessibleInterface *childInterface = child(i);
160 if (childInterface->rect().contains(x,y)) {
161 return childInterface;
162 }
163 }
164 return nullptr;
165}
166
167int QAccessibleMenuItem::childCount() const
168{
169 return m_action->menu() ? 1 : 0;
170}
171
172int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const
173{
174 if (child && child->role() == QAccessible::PopupMenu && child->object() == m_action->menu())
175 return 0;
176 return -1;
177}
178
179bool QAccessibleMenuItem::isValid() const
180{
181 return m_action && m_owner;
182}
183
184QAccessibleInterface *QAccessibleMenuItem::parent() const
185{
186 return QAccessible::queryAccessibleInterface(owner());
187}
188
189QAccessibleInterface *QAccessibleMenuItem::child(int index) const
190{
191 if (index == 0 && action()->menu())
192 return QAccessible::queryAccessibleInterface(action()->menu());
193 return nullptr;
194}
195
196void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t)
197{
198 if (t == QAccessible::ActionInterface)
199 return static_cast<QAccessibleActionInterface*>(this);
200 return nullptr;
201}
202
203QObject *QAccessibleMenuItem::object() const
204{
205 return m_action;
206}
207
209QWindow *QAccessibleMenuItem::window() const
210{
211 return m_owner.isNull()
212 ? nullptr
213 : qt_widget_private(m_owner.data())->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
214}
215
216QRect QAccessibleMenuItem::rect() const
217{
218 QRect rect;
219 QWidget *own = owner();
220#if QT_CONFIG(menubar)
221 if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
222 rect = menuBar->actionGeometry(m_action);
223 QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
224 rect = rect.translated(globalPos);
225 } else
226#endif // QT_CONFIG(menubar)
227 if (QMenu *menu = qobject_cast<QMenu*>(own)) {
228 rect = menu->actionGeometry(m_action);
229 QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
230 rect = rect.translated(globalPos);
231 }
232 return rect;
233}
234
235QAccessible::Role QAccessibleMenuItem::role() const
236{
237 return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem;
238}
239
240void QAccessibleMenuItem::setText(QAccessible::Text /*t*/, const QString & /*text */)
241{
242}
243
244QAccessible::State QAccessibleMenuItem::state() const
245{
247 QWidget *own = owner();
248
249 if (own && (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false)) {
250 s.invisible = true;
251 }
252
253 if (QMenu *menu = qobject_cast<QMenu*>(own)) {
254 if (menu->activeAction() == m_action)
255 s.focused = true;
256#if QT_CONFIG(menubar)
257 } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
258 if (menuBar->activeAction() == m_action)
259 s.focused = true;
260#endif
261 }
263 s.hotTracked = true;
264 if (m_action->isSeparator() || !m_action->isEnabled())
265 s.disabled = true;
266 if (m_action->isChecked())
267 s.checked = true;
268 if (m_action->isCheckable())
269 s.checkable = true;
270
271 return s;
272}
273
274QString QAccessibleMenuItem::text(QAccessible::Text t) const
275{
276 QString str;
277 switch (t) {
278 case QAccessible::Name:
279 str = qt_accStripAmp(m_action->text());
280 break;
281 case QAccessible::Accelerator: {
282#ifndef QT_NO_SHORTCUT
283 QKeySequence key = m_action->shortcut();
284 if (!key.isEmpty()) {
285 str = key.toString();
286 } else
287#endif
288 {
289 str = qt_accHotKey(m_action->text());
290 }
291 break;
292 }
293 default:
294 break;
295 }
296 return str;
297}
298
299QStringList QAccessibleMenuItem::actionNames() const
300{
301 QStringList actions;
302 if (!m_action || m_action->isSeparator())
303 return actions;
304
305 if (m_action->menu()) {
306 actions << showMenuAction();
307 } else {
308 actions << pressAction();
309 }
310 return actions;
311}
312
313void QAccessibleMenuItem::doAction(const QString &actionName)
314{
315 if (!m_action->isEnabled())
316 return;
317
318 if (actionName == pressAction()) {
319 m_action->trigger();
320 } else if (actionName == showMenuAction()) {
321#if QT_CONFIG(menubar)
322 if (QMenuBar *bar = qobject_cast<QMenuBar*>(owner())) {
323 if (m_action->menu() && m_action->menu()->isVisible()) {
324 m_action->menu()->hide();
325 } else {
326 bar->setActiveAction(m_action);
327 }
328 } else
329#endif
330 if (QMenu *menu = qobject_cast<QMenu*>(owner())){
331 if (m_action->menu() && m_action->menu()->isVisible()) {
332 m_action->menu()->hide();
333 } else {
334 menu->setActiveAction(m_action);
335 }
336 }
337 }
338}
339
340QStringList QAccessibleMenuItem::keyBindingsForAction(const QString &) const
341{
342 return QStringList();
343}
344
345
346QAction *QAccessibleMenuItem::action() const
347{
348 return m_action;
349}
350
351QWidget *QAccessibleMenuItem::owner() const
352{
353 return m_owner;
354}
355
356#endif // QT_CONFIG(menu)
357
359
360#endif // QT_CONFIG(accessibility)
361
\inmodule QtGui
The QAccessible class provides enums and static functions related to accessibility.
The QAction class provides an abstraction for user commands that can be added to different user inter...
Definition qaction.h:30
bool isSeparator() const
Returns true if this action is a separator action; otherwise it returns false.
Definition qaction.cpp:585
The QKeySequence class encapsulates a key sequence as used by shortcuts.
qsizetype size() const noexcept
Definition qlist.h:397
The QMenuBar class provides a horizontal menu bar.
Definition qmenubar.h:20
QRect actionGeometry(QAction *) const
Returns the geometry of action act as a QRect.
QAction * activeAction() const
Returns the QAction that is currently highlighted, if any, else \nullptr.
Definition qmenubar.cpp:819
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus.
Definition qmenu.h:26
QAction * actionAt(const QPoint &) const
Returns the item at pt; returns \nullptr if there is no item there.
Definition qmenu.cpp:2251
void setActiveAction(QAction *act)
Sets the currently highlighted action to act.
Definition qmenu.cpp:2180
QRect actionGeometry(QAction *) const
Returns the geometry of action act.
Definition qmenu.cpp:2261
QAction * activeAction() const
Returns the currently highlighted action, or \nullptr if no action is currently highlighted.
Definition qmenu.cpp:2193
\inmodule QtCore
Definition qobject.h:103
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
@ SH_Menu_MouseTracking
Definition qstyle.h:605
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QPointF mapToGlobal(const QPointF &) const
Translates the widget coordinate pos to global screen coordinates.
QList< QAction * > actions() const
Returns the (possibly empty) list of this widget's actions.
Definition qwidget.cpp:3207
QStyle * style() const
Definition qwidget.cpp:2600
QString windowTitle
the window title (caption)
Definition qwidget.h:151
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition qwidget.h:910
\inmodule QtGui
Definition qwindow.h:63
QOpenGLWidget * widget
[1]
QString str
[2]
QString text
rect
[4]
Combined button and popup list for selecting options.
constexpr QBindableInterface iface
Definition qproperty.h:666
@ WA_WState_Visible
Definition qnamespace.h:296
QList< QString > QStringList
Constructs a string list that contains the given string, str.
GLint GLint GLint GLint GLint x
[0]
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLboolean r
[2]
GLuint object
[3]
GLint y
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QT_CONFIG(feature)
Q_WIDGETS_EXPORT QWidgetPrivate * qt_widget_private(QWidget *widget)
QObject::connect nullptr
QLayoutItem * child
[0]
QMenu menu
[5]
QAction * at
QMenuBar * menuBar
[0]
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:962