Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qaction.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 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// Qt-Security score:significant reason:default
4
5#include "qaction.h"
6#include "qactiongroup.h"
7
8#include "qaction_p.h"
10#include "qevent.h"
11#include "qlist.h"
12#include "qstylehints.h"
13#if QT_CONFIG(shortcut)
14# include <private/qshortcutmap_p.h>
15#endif
16#include <private/qguiapplication_p.h>
17#include <private/qdebug_p.h>
18
19#define QAPP_CHECK(functionName)
20 if (Q_UNLIKELY(!QCoreApplication::instance())) {
21 qWarning("QAction: Initialize Q(Gui)Application before calling '" functionName "'.");
22 return;
23 }
24
26
27using namespace Qt::StringLiterals;
28
29/*
30 internal: guesses a descriptive text from a text suited for a menu entry
31 */
32static QString qt_strippedText(QString s)
33{
34 for (qsizetype i = 0; i < s.size(); ++i) {
35 const QChar &c = s.at(i);
36 if (c == u'&' || c == u'\x2026') // Horizontal Ellipsis
37 s.remove(i, 1);
38 else if (i + 2 < s.size() && c == u'.' && s.at(i + 1) == u'.' && s.at(i + 2) == u'.')
39 s.remove(i, 3);
40 }
41 return s.trimmed();
42}
43
44QActionPrivate *QGuiApplicationPrivate::createActionPrivate() const
45{
46 return new QActionPrivate;
47}
48
49QActionPrivate::QActionPrivate() :
50#if QT_CONFIG(shortcut)
51 autorepeat(1),
52#endif
53 enabled(1), explicitEnabled(0), explicitEnabledValue(1), visible(1), forceInvisible(0), checkable(0),
54 checked(0), separator(0), fontSet(false),
55 iconVisibleInMenu(-1), shortcutVisibleInContextMenu(-1)
56{
57}
58
59#if QT_CONFIG(shortcut)
60static bool dummy(QObject *, Qt::ShortcutContext) { return false; } // only for GUI testing.
61
62QShortcutMap::ContextMatcher QActionPrivate::contextMatcher() const
63{
64 return dummy;
65};
66#endif // QT_CONFIG(shortcut)
67
68QActionPrivate::~QActionPrivate() = default;
69
70void QActionPrivate::destroy()
71{
72}
73
74void QActionPrivate::sendDataChanged()
75{
76 Q_Q(QAction);
77 QActionEvent e(QEvent::ActionChanged, q);
78 QCoreApplication::sendEvent(q, &e);
79
80 emit q->changed();
81}
82
83#if QT_CONFIG(shortcut)
84void QActionPrivate::redoGrab(QShortcutMap &map)
85{
86 Q_Q(QAction);
87 for (int id : std::as_const(shortcutIds)) {
88 if (id)
89 map.removeShortcut(id, q);
90 }
91
92 shortcutIds.clear();
93 for (const QKeySequence &shortcut : std::as_const(shortcuts)) {
94 if (!shortcut.isEmpty())
95 shortcutIds.append(map.addShortcut(q, shortcut, shortcutContext, contextMatcher()));
96 else
97 shortcutIds.append(0);
98 }
99 if (!enabled) {
100 for (int id : std::as_const(shortcutIds)) {
101 if (id)
102 map.setShortcutEnabled(false, id, q);
103 }
104 }
105 if (!autorepeat) {
106 for (int id : std::as_const(shortcutIds)) {
107 if (id)
108 map.setShortcutAutoRepeat(false, id, q);
109 }
110 }
111}
112
113void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
114{
115 Q_Q(QAction);
116 for (int id : std::as_const(shortcutIds)) {
117 if (id)
118 map.setShortcutEnabled(enable, id, q);
119 }
120}
121#endif // QT_NO_SHORTCUT
122
123bool QActionPrivate::showStatusText(QObject *object, const QString &str)
124{
125 if (QObject *receiver = object ? object : parent) {
126 QStatusTipEvent tip(str);
127 QCoreApplication::sendEvent(receiver, &tip);
128 return true;
129 }
130 return false;
131}
132
133void QActionPrivate::setMenu(QObject *)
134{
135}
136
137QObject *QActionPrivate::menu() const
138{
139 return nullptr;
140}
141
142/*!
143 \class QAction
144 \brief The QAction class provides an abstraction for user commands
145 that can be added to different user interface components.
146 \since 6.0
147
148 \inmodule QtGui
149
150 In applications many common commands can be invoked via menus,
151 toolbar buttons, and keyboard shortcuts. Since the user expects
152 each command to be performed in the same way, regardless of the
153 user interface used, it is useful to represent each command as
154 an \e action.
155
156 Actions can be added to user interface elements such as menus and toolbars,
157 and will automatically keep the UI in sync. For example, in a word
158 processor, if the user presses a Bold toolbar button, the Bold menu item
159 will automatically be checked.
160
161 A QAction may contain an icon, descriptive text, icon text, a keyboard
162 shortcut, status text, "What's This?" text, and a tooltip. All properties
163 can be set independently with setIcon(), setText(), setIconText(),
164 setShortcut(), setStatusTip(), setWhatsThis(), and setToolTip(). Icon and
165 text, as the two most important properties, can also be set in the
166 constructor. It's possible to set an individual font with setFont(), which
167 e.g. menus respect when displaying the action as a menu item.
168
169 We recommend that actions are created as children of the window
170 they are used in. In most cases actions will be children of
171 the application's main window.
172
173 \section1 QAction in widget applications
174
175 Once a QAction has been created, it should be added to the relevant
176 menu and toolbar, then connected to the slot which will perform
177 the action.
178
179 Actions are added to widgets using QWidget::addAction() or
180 QGraphicsWidget::addAction(). Note that an action must be added to a
181 widget before it can be used. This is also true when the shortcut should
182 be global (i.e., Qt::ApplicationShortcut as Qt::ShortcutContext).
183
184 Actions can be created as independent objects. But they may
185 also be created during the construction of menus. The QMenu class
186 contains convenience functions for creating actions suitable for
187 use as menu items.
188
189
190 \sa QMenu, QToolBar
191*/
192
193/*!
194 \fn void QAction::trigger()
195
196 This is a convenience slot that calls activate(Trigger).
197*/
198
199/*!
200 \fn void QAction::hover()
201
202 This is a convenience slot that calls activate(Hover).
203*/
204
205/*!
206 \enum QAction::MenuRole
207
208 This enum describes how an action should be moved into the application menu on \macos.
209
210 \value NoRole This action should not be put into the application menu
211 \value TextHeuristicRole This action should be put in the application menu based on the action's text
212 as described in the QMenuBar documentation.
213 \value ApplicationSpecificRole This action should be put in the application menu with an application specific role
214 \value AboutQtRole This action handles the "About Qt" menu item.
215 \value AboutRole This action should be placed where the "About" menu item is in the application menu. The text of
216 the menu item will be set to "About <application name>". The application name is fetched from the
217 \c{Info.plist} file in the application's bundle (See \l{Qt for macOS - Deployment}).
218 \value PreferencesRole This action should be placed where the "Preferences..." menu item is in the application menu.
219 \value QuitRole This action should be placed where the Quit menu item is in the application menu.
220
221 Setting this value only has effect on items that are in the immediate menus
222 of the menubar, not the submenus of those menus. For example, if you have
223 File menu in your menubar and the File menu has a submenu, setting the
224 MenuRole for the actions in that submenu have no effect. They will never be moved.
225*/
226
227/*!
228 Constructs an action with \a parent. If \a parent is an action
229 group the action will be automatically inserted into the group.
230
231 \note The \a parent argument is optional since Qt 5.7.
232*/
233QAction::QAction(QObject *parent)
234 : QAction(*QGuiApplicationPrivate::instance()->createActionPrivate(), parent)
235{
236}
237
238/*!
239 Constructs an action with some \a text and \a parent. If \a
240 parent is an action group the action will be automatically
241 inserted into the group.
242
243 A stripped version of \a text (for example, "\&Menu Option..." becomes
244 "Menu Option") will be used for tooltips and icon text unless you specify a
245 different text using setToolTip() or setIconText(), respectively.
246
247 \sa text
248*/
249QAction::QAction(const QString &text, QObject *parent)
250 : QAction(parent)
251{
252 Q_D(QAction);
253 d->text = text;
254}
255
256/*!
257 Constructs an action with an \a icon and some \a text and \a
258 parent. If \a parent is an action group the action will be
259 automatically inserted into the group.
260
261 A stripped version of \a text (for example, "\&Menu Option..." becomes
262 "Menu Option") will be used for tooltips and icon text unless you specify a
263 different text using setToolTip() or setIconText(), respectively.
264
265 \sa text, icon
266*/
267QAction::QAction(const QIcon &icon, const QString &text, QObject *parent)
268 : QAction(text, parent)
269{
270 Q_D(QAction);
271 d->icon = icon;
272}
273
274/*!
275 \internal
276*/
277QAction::QAction(QActionPrivate &dd, QObject *parent)
278 : QObject(dd, parent)
279{
280 Q_D(QAction);
281 d->group = qobject_cast<QActionGroup *>(parent);
282 if (d->group)
283 d->group->addAction(this);
284}
285
286#if QT_CONFIG(shortcut)
287/*!
288 \property QAction::shortcut
289 \brief the action's primary shortcut key
290
291 Valid keycodes for this property can be found in \l Qt::Key and
292 \l Qt::Modifier. There is no default shortcut key.
293*/
294
295/*!
296 Sets \a shortcut as the sole shortcut that triggers the action.
297
298 \sa shortcut, setShortcuts()
299*/
300void QAction::setShortcut(const QKeySequence &shortcut)
301{
302 if (shortcut.isEmpty())
303 setShortcuts({});
304 else
305 setShortcuts({ shortcut });
306}
307
308/*!
309 Sets \a shortcuts as the list of shortcuts that trigger the
310 action. The first element of the list is the primary shortcut.
311
312 \sa shortcut, setShortcut()
313*/
314void QAction::setShortcuts(const QList<QKeySequence> &shortcuts)
315{
316 QAPP_CHECK("setShortcuts");
317 Q_D(QAction);
318
319 if (d->shortcuts == shortcuts)
320 return;
321
322 d->shortcuts = shortcuts;
323 d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
324 d->sendDataChanged();
325}
326
327/*!
328 Sets a platform dependent list of shortcuts based on the \a key.
329 The result of calling this function will depend on the currently running platform.
330 Note that more than one shortcut can assigned by this action.
331 If only the primary shortcut is required, use setShortcut instead.
332
333 \sa QKeySequence::keyBindings()
334*/
335void QAction::setShortcuts(QKeySequence::StandardKey key)
336{
337 QList <QKeySequence> list = QKeySequence::keyBindings(key);
338 setShortcuts(list);
339}
340
341/*!
342 Returns the primary shortcut.
343
344 \sa setShortcuts()
345*/
346QKeySequence QAction::shortcut() const
347{
348 Q_D(const QAction);
349 if (d->shortcuts.isEmpty())
350 return QKeySequence();
351 return d->shortcuts.first();
352}
353
354/*!
355 Returns the list of shortcuts, with the primary shortcut as
356 the first element of the list.
357
358 \sa setShortcuts()
359*/
360QList<QKeySequence> QAction::shortcuts() const
361{
362 Q_D(const QAction);
363 return d->shortcuts;
364}
365
366/*!
367 \property QAction::shortcutContext
368 \brief the context for the action's shortcut
369
370 Valid values for this property can be found in \l Qt::ShortcutContext.
371 The default value is Qt::WindowShortcut.
372*/
373void QAction::setShortcutContext(Qt::ShortcutContext context)
374{
375 Q_D(QAction);
376 if (d->shortcutContext == context)
377 return;
378 QAPP_CHECK("setShortcutContext");
379 d->shortcutContext = context;
380 d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
381 d->sendDataChanged();
382}
383
384Qt::ShortcutContext QAction::shortcutContext() const
385{
386 Q_D(const QAction);
387 return d->shortcutContext;
388}
389
390/*!
391 \property QAction::autoRepeat
392 \brief whether the action can auto repeat
393
394 If true, the action will auto repeat when the keyboard shortcut
395 combination is held down, provided that keyboard auto repeat is
396 enabled on the system.
397 The default value is true.
398*/
399void QAction::setAutoRepeat(bool on)
400{
401 Q_D(QAction);
402 if (d->autorepeat == on)
403 return;
404 QAPP_CHECK("setAutoRepeat");
405 d->autorepeat = on;
406 d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
407 d->sendDataChanged();
408}
409
410bool QAction::autoRepeat() const
411{
412 Q_D(const QAction);
413 return d->autorepeat;
414}
415#endif // QT_CONFIG(shortcut)
416
417/*!
418 \property QAction::font
419 \brief the action's font
420
421 The font property is used to render the text set on the
422 QAction. The font can be considered a hint as it will not be
423 consulted in all cases based upon application and style.
424
425 By default, this property contains the application's default font.
426
427 \sa setText()
428*/
429void QAction::setFont(const QFont &font)
430{
431 Q_D(QAction);
432 if (d->font == font)
433 return;
434
435 d->fontSet = true;
436 d->font = font;
437 d->sendDataChanged();
438}
439
440QFont QAction::font() const
441{
442 Q_D(const QAction);
443 return d->font;
444}
445
446
447/*!
448 Destroys the object and frees allocated resources.
449*/
450QAction::~QAction()
451{
452 Q_D(QAction);
453
454 d->destroy();
455
456 if (d->group)
457 d->group->removeAction(this);
458#if QT_CONFIG(shortcut)
459 if (qApp) {
460 for (int id : std::as_const(d->shortcutIds)) {
461 if (id)
462 QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id, this);
463 }
464 }
465#endif
466}
467
468/*!
469 Sets this action group to \a group. The action will be automatically
470 added to the group's list of actions.
471
472 Actions within the group will be mutually exclusive.
473
474 \sa QActionGroup, actionGroup()
475*/
476void QAction::setActionGroup(QActionGroup *group)
477{
478 Q_D(QAction);
479 if (group == d->group)
480 return;
481
482 if (d->group)
483 d->group->removeAction(this);
484 d->group = group;
485 if (group)
486 group->addAction(this);
487 d->sendDataChanged();
488}
489
490/*!
491 Returns the action group for this action. If no action group manages
492 this action, then \nullptr will be returned.
493
494 \sa QActionGroup, setActionGroup()
495*/
496QActionGroup *QAction::actionGroup() const
497{
498 Q_D(const QAction);
499 return d->group;
500}
501
502/*!
503 \since 6.0
504 Returns a list of objects this action has been added to.
505
506 \sa QWidget::addAction(), QGraphicsWidget::addAction()
507*/
508QList<QObject*> QAction::associatedObjects() const
509{
510 Q_D(const QAction);
511 return d->associatedObjects;
512}
513
514/*!
515 \fn QWidget *QAction::parentWidget() const
516 \deprecated [6.0] Use parent() with qobject_cast() instead.
517
518 Returns the parent widget.
519*/
520
521/*!
522 \fn QList<QWidget*> QAction::associatedWidgets() const
523 \deprecated [6.0] Use associatedObjects() with qobject_cast() instead.
524
525 Returns a list of widgets this action has been added to.
526
527 \sa QWidget::addAction(), associatedObjects(), associatedGraphicsWidgets()
528*/
529
530/*!
531 \fn QList<QWidget*> QAction::associatedGraphicsWidgets() const
532 \deprecated [6.0] Use associatedObjects() with qobject_cast() instead.
533
534 Returns a list of graphics widgets this action has been added to.
535
536 \sa QGraphicsWidget::addAction(), associatedObjects(), associatedWidgets()
537*/
538
539/*!
540 \property QAction::icon
541 \brief the action's icon
542
543 In toolbars, the icon is used as the tool button icon; in menus,
544 it is displayed to the left of the menu text, as long as
545 QAction::iconVisibleInMenu returns \c true.
546
547 There is no default icon.
548
549 If a null icon (QIcon::isNull()) is passed into this function,
550 the icon of the action is cleared.
551*/
552void QAction::setIcon(const QIcon &icon)
553{
554 Q_D(QAction);
555 d->icon = icon;
556 d->sendDataChanged();
557}
558
559QIcon QAction::icon() const
560{
561 Q_D(const QAction);
562 return d->icon;
563}
564
565/*!
566 If \a b is true then this action will be considered a separator.
567
568 How a separator is represented depends on the widget it is inserted
569 into. Under most circumstances the text, submenu, and icon will be
570 ignored for separator actions.
571
572 \sa isSeparator()
573*/
574void QAction::setSeparator(bool b)
575{
576 Q_D(QAction);
577 if (d->separator == b)
578 return;
579
580 d->separator = b;
581 d->sendDataChanged();
582}
583
584/*!
585 Returns \c true if this action is a separator action; otherwise it
586 returns \c false.
587
588 \sa setSeparator()
589*/
590bool QAction::isSeparator() const
591{
592 Q_D(const QAction);
593 return d->separator;
594}
595
596/*!
597 \property QAction::text
598 \brief the action's descriptive text
599
600 If the action is added to a menu, the menu option will consist of
601 the icon (if there is one), the text, and the shortcut (if there
602 is one). If the text is not explicitly set in the constructor, or
603 by using setText(), the action's description icon text will be
604 used as text. There is no default text.
605
606 Certain UI elements, such as menus or buttons, can use '&' in front of a
607 character to automatically create a mnemonic (a shortcut) for that
608 character. For example, "&File" for a menu will create the shortcut
609 \uicontrol Alt+F, which will open the File menu. "E&xit" will create the
610 shortcut \uicontrol Alt+X for a button, or in a menu allow navigating to
611 the menu item by pressing "x". (use '&&' to display an actual ampersand).
612 The widget might consume and perform an action on a given shortcut.
613
614 \sa iconText
615*/
616void QAction::setText(const QString &text)
617{
618 Q_D(QAction);
619 if (d->text == text)
620 return;
621
622 d->text = text;
623 d->sendDataChanged();
624}
625
626QString QAction::text() const
627{
628 Q_D(const QAction);
629 QString s = d->text;
630 if (s.isEmpty()) {
631 s = d->iconText;
632 s.replace(u'&', "&&"_L1);
633 }
634 return s;
635}
636
637/*!
638 \property QAction::iconText
639 \brief the action's descriptive icon text
640
641 If QToolBar::toolButtonStyle is set to a value that permits text to
642 be displayed, the text defined held in this property appears as a
643 label in the relevant tool button.
644
645 It also serves as the default text in menus and tooltips if the action
646 has not been defined with setText() or setToolTip(), and will
647 also be used in toolbar buttons if no icon has been defined using setIcon().
648
649 If the icon text is not explicitly set, the action's normal text will be
650 used for the icon text.
651
652 By default, this property contains an empty string.
653
654 \sa setToolTip(), setStatusTip()
655*/
656void QAction::setIconText(const QString &text)
657{
658 Q_D(QAction);
659 if (d->iconText == text)
660 return;
661
662 d->iconText = text;
663 d->sendDataChanged();
664}
665
666QString QAction::iconText() const
667{
668 Q_D(const QAction);
669 if (d->iconText.isEmpty())
670 return qt_strippedText(d->text);
671 return d->iconText;
672}
673
674/*!
675 \property QAction::toolTip
676 \brief the action's tooltip
677
678 This text is used for the tooltip. If no tooltip is specified,
679 the action's text is used.
680
681 By default, this property contains the action's text.
682
683 \sa setStatusTip(), setShortcut()
684*/
685void QAction::setToolTip(const QString &tooltip)
686{
687 Q_D(QAction);
688 if (d->tooltip == tooltip)
689 return;
690
691 d->tooltip = tooltip;
692 d->sendDataChanged();
693}
694
695QString QAction::toolTip() const
696{
697 Q_D(const QAction);
698 if (d->tooltip.isEmpty()) {
699 if (!d->text.isEmpty())
700 return qt_strippedText(d->text);
701 return qt_strippedText(d->iconText);
702 }
703 return d->tooltip;
704}
705
706/*!
707 \property QAction::statusTip
708 \brief the action's status tip
709
710 The status tip is displayed on all status bars provided by the
711 action's top-level parent widget.
712
713 By default, this property contains an empty string.
714
715 \sa setToolTip(), showStatusText()
716*/
717void QAction::setStatusTip(const QString &statustip)
718{
719 Q_D(QAction);
720 if (d->statustip == statustip)
721 return;
722
723 d->statustip = statustip;
724 d->sendDataChanged();
725}
726
727QString QAction::statusTip() const
728{
729 Q_D(const QAction);
730 return d->statustip;
731}
732
733/*!
734 Updates the relevant status bar for the UI represented by \a object by sending a
735 QStatusTipEvent. Returns \c true if an event was sent, otherwise returns \c false.
736
737 If a null widget is specified, the event is sent to the action's parent.
738
739 \sa statusTip
740*/
741bool QAction::showStatusText(QObject *object)
742{
743 Q_D(QAction);
744 return d->showStatusText(object, statusTip());
745}
746
747/*!
748 \property QAction::whatsThis
749 \brief the action's "What's This?" help text
750
751 The "What's This?" text is used to provide a brief description of
752 the action. The text may contain rich text. There is no default
753 "What's This?" text.
754
755 \sa QWhatsThis
756*/
757void QAction::setWhatsThis(const QString &whatsthis)
758{
759 Q_D(QAction);
760 if (d->whatsthis == whatsthis)
761 return;
762
763 d->whatsthis = whatsthis;
764 d->sendDataChanged();
765}
766
767QString QAction::whatsThis() const
768{
769 Q_D(const QAction);
770 return d->whatsthis;
771}
772
773/*!
774 \enum QAction::Priority
775
776 This enum defines priorities for actions in user interface.
777
778 \value LowPriority The action should not be prioritized in
779 the user interface.
780
781 \value NormalPriority
782
783 \value HighPriority The action should be prioritized in
784 the user interface.
785
786 \sa priority
787*/
788
789
790/*!
791 \property QAction::priority
792
793 \brief the actions's priority in the user interface.
794
795 This property can be set to indicate how the action should be prioritized
796 in the user interface.
797
798 For instance, when toolbars have the Qt::ToolButtonTextBesideIcon
799 mode set, then actions with LowPriority will not show the text
800 labels.
801*/
802void QAction::setPriority(Priority priority)
803{
804 Q_D(QAction);
805 if (d->priority == priority)
806 return;
807
808 d->priority = priority;
809 d->sendDataChanged();
810}
811
812QAction::Priority QAction::priority() const
813{
814 Q_D(const QAction);
815 return d->priority;
816}
817
818/*!
819 \property QAction::checkable
820 \brief whether the action is a checkable action
821
822 A checkable action is one which has an on/off state. For example,
823 in a word processor, a Bold toolbar button may be either on or
824 off. An action which is not a toggle action is a command action;
825 a command action is simply executed, e.g. file save.
826 By default, this property is \c false.
827
828 In some situations, the state of one toggle action should depend
829 on the state of others. For example, "Left Align", "Center" and
830 "Right Align" toggle actions are mutually exclusive. To achieve
831 exclusive toggling, add the relevant toggle actions to a
832 QActionGroup with the QActionGroup::exclusive property set to
833 true.
834
835 \sa setChecked()
836*/
837void QAction::setCheckable(bool b)
838{
839 Q_D(QAction);
840 if (d->checkable == b)
841 return;
842
843 d->checkable = b;
844 QPointer<QAction> guard(this);
845 d->sendDataChanged();
846 if (guard)
847 emit checkableChanged(b);
848 if (guard && d->checked)
849 emit toggled(b);
850}
851
852bool QAction::isCheckable() const
853{
854 Q_D(const QAction);
855 return d->checkable;
856}
857
858/*!
859 \fn void QAction::toggle()
860
861 This is a convenience function for the \l checked property.
862 Connect to it to change the checked state to its opposite state.
863*/
864void QAction::toggle()
865{
866 Q_D(QAction);
867 setChecked(!d->checked);
868}
869
870/*!
871 \property QAction::checked
872 \brief whether the action is checked.
873
874 Only checkable actions can be checked. By default, this is false
875 (the action is unchecked).
876
877 \note The notifier signal for this property is toggled(). As toggling
878 a QAction changes its state, it will also emit a changed() signal.
879
880 \sa checkable, toggled()
881*/
882void QAction::setChecked(bool b)
883{
884 Q_D(QAction);
885 if (d->checked == b)
886 return;
887
888 d->checked = b;
889 if (!d->checkable)
890 return;
891 QPointer<QAction> guard(this);
892 d->sendDataChanged();
893 if (guard)
894 emit toggled(b);
895}
896
897bool QAction::isChecked() const
898{
899 Q_D(const QAction);
900 return d->checked && d->checkable;
901}
902
903/*!
904 \fn void QAction::setDisabled(bool b)
905
906 This is a convenience function for the \l enabled property, that
907 is useful for signals--slots connections. If \a b is true the
908 action is disabled; otherwise it is enabled.
909*/
910
911/*!
912 \property QAction::enabled
913 \brief whether the action is enabled
914
915 Disabled actions cannot be chosen by the user. They do not
916 disappear from menus or toolbars, but they are displayed in a way
917 which indicates that they are unavailable. For example, they might
918 be displayed using only shades of gray.
919
920 \uicontrol{What's This?} help on disabled actions is still available, provided
921 that the QAction::whatsThis property is set.
922
923 An action will be disabled when all widgets to which it is added
924 (with QWidget::addAction()) are disabled or not visible. When an
925 action is disabled, it is not possible to trigger it through its
926 shortcut.
927
928 By default, this property is \c true (actions are enabled).
929
930 \sa text
931*/
932void QAction::setEnabled(bool b)
933{
934 Q_D(QAction);
935 if (d->explicitEnabledValue == b && d->explicitEnabled)
936 return;
937 d->explicitEnabledValue = b;
938 d->explicitEnabled = true;
939 QAPP_CHECK("setEnabled");
940 d->setEnabled(b, false);
941}
942
943bool QActionPrivate::setEnabled(bool b, bool byGroup)
944{
945 Q_Q(QAction);
946 if (b && !visible)
947 b = false;
948 if (b && !byGroup && (group && !group->isEnabled()))
949 b = false;
950 if (b && byGroup && explicitEnabled)
951 b = explicitEnabledValue;
952
953 if (b == enabled)
954 return false;
955
956 enabled = b;
957#if QT_CONFIG(shortcut)
958 setShortcutEnabled(b, QGuiApplicationPrivate::instance()->shortcutMap);
959#endif
960 QPointer guard(q);
961 sendDataChanged();
962 if (guard)
963 emit q->enabledChanged(b);
964 return true;
965}
966
967void QAction::resetEnabled()
968{
969 Q_D(QAction);
970 if (!d->explicitEnabled)
971 return;
972 d->explicitEnabled = false;
973 d->setEnabled(true, false);
974}
975
976bool QAction::isEnabled() const
977{
978 Q_D(const QAction);
979 return d->enabled;
980}
981
982/*!
983 \property QAction::visible
984 \brief whether the action can be seen (e.g. in menus and toolbars)
985
986 If \e visible is true the action can be seen (e.g. in menus and
987 toolbars) and chosen by the user; if \e visible is false the
988 action cannot be seen or chosen by the user.
989
990 Actions which are not visible are \e not grayed out; they do not
991 appear at all.
992
993 By default, this property is \c true (actions are visible).
994*/
995void QAction::setVisible(bool b)
996{
997 Q_D(QAction);
998 if (b != d->forceInvisible)
999 return;
1000 d->forceInvisible = !b;
1001 if (b && d->group && !d->group->isVisible())
1002 return;
1003 d->setVisible(b);
1004}
1005
1006void QActionPrivate::setVisible(bool b)
1007{
1008 Q_Q(QAction);
1009 if (b == visible)
1010 return;
1011 QAPP_CHECK("setVisible");
1012 visible = b;
1013 bool enable = visible;
1014 if (enable && explicitEnabled)
1015 enable = explicitEnabledValue;
1016 QPointer guard(q);
1017 if (!setEnabled(enable, false))
1018 sendDataChanged();
1019 if (guard)
1020 emit q->visibleChanged();
1021}
1022
1023bool QAction::isVisible() const
1024{
1025 Q_D(const QAction);
1026 return d->visible;
1027}
1028
1029/*!
1030 \reimp
1031*/
1032bool QAction::event(QEvent *e)
1033{
1034 Q_D(QAction);
1035 if (e->type() == QEvent::ActionChanged) {
1036 for (auto object : std::as_const(d->associatedObjects))
1037 QCoreApplication::sendEvent(object, e);
1038 }
1039
1040#if QT_CONFIG(shortcut)
1041 if (e->type() == QEvent::Shortcut) {
1042 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
1043 Q_ASSERT_X(d_func()->shortcutIds.contains(se->shortcutId()),
1044 "QAction::event",
1045 "Received shortcut event from incorrect shortcut");
1046 if (se->isAmbiguous())
1047 qWarning("QAction::event: Ambiguous shortcut overload: %s", se->key().toString(QKeySequence::NativeText).toLatin1().constData());
1048 else
1049 activate(Trigger);
1050 return true;
1051 }
1052#endif // QT_CONFIG(shortcut)
1053 return QObject::event(e);
1054}
1055
1056/*!
1057 Returns the user data as set in QAction::setData.
1058
1059 \sa setData()
1060*/
1061QVariant QAction::data() const
1062{
1063 Q_D(const QAction);
1064 return d->userData;
1065}
1066
1067/*!
1068 Sets the action's internal data to the given \a data.
1069
1070 \sa data()
1071*/
1072void QAction::setData(const QVariant &data)
1073{
1074 Q_D(QAction);
1075 if (d->userData == data)
1076 return;
1077 d->userData = data;
1078 d->sendDataChanged();
1079}
1080
1081/*!
1082 Sends the relevant signals for ActionEvent \a event.
1083
1084 Action-based widgets use this API to cause the QAction
1085 to emit signals as well as emitting their own.
1086*/
1087void QAction::activate(ActionEvent event)
1088{
1089 Q_D(QAction);
1090 if (event == Trigger) {
1091 // Ignore even explicit triggers when explicitly disabled
1092 if ((d->explicitEnabled && !d->explicitEnabledValue) || (d->group && !d->group->isEnabled()))
1093 return;
1094 QPointer<QObject> guard = this;
1095 if (d->checkable) {
1096 // the checked action of an exclusive group may not be unchecked
1097 if (d->checked && (d->group
1098 && d->group->exclusionPolicy() == QActionGroup::ExclusionPolicy::Exclusive
1099 && d->group->checkedAction() == this)) {
1100 if (!guard.isNull())
1101 emit triggered(true);
1102 return;
1103 }
1104 setChecked(!d->checked);
1105 }
1106 if (!guard.isNull())
1107 emit triggered(d->checked);
1108 } else if (event == Hover) {
1109 emit hovered();
1110 }
1111}
1112
1113/*!
1114 \fn void QAction::triggered(bool checked)
1115
1116 This signal is emitted when an action is activated by the user;
1117 for example, when the user clicks a menu option, toolbar button,
1118 or presses an action's shortcut key combination, or when trigger()
1119 was called. Notably, it is \e not emitted when setChecked() or
1120 toggle() is called.
1121
1122 If the action is checkable, \a checked is true if the action is
1123 checked, or false if the action is unchecked.
1124
1125 \sa activate(), toggled(), checked
1126*/
1127
1128/*!
1129 \fn void QAction::toggled(bool checked)
1130
1131 This signal is emitted whenever a checkable action changes its
1132 isChecked() status. This can be the result of a user interaction,
1133 or because setChecked() was called. As setChecked() changes the
1134 QAction, it emits changed() in addition to toggled().
1135
1136 \a checked is true if the action is checked, or false if the
1137 action is unchecked.
1138
1139 \sa activate(), triggered(), checked
1140*/
1141
1142/*!
1143 \fn void QAction::hovered()
1144
1145 This signal is emitted when an action is highlighted by the user;
1146 for example, when the user pauses with the cursor over a menu option,
1147 toolbar button, or presses an action's shortcut key combination.
1148
1149 \sa activate()
1150*/
1151
1152/*!
1153 \fn void QAction::changed()
1154
1155 This signal is emitted when an action has changed. If you
1156 are only interested in actions in a given widget, you can
1157 watch for QWidget::actionEvent() sent with an
1158 QEvent::ActionChanged.
1159
1160 \sa QWidget::actionEvent()
1161*/
1162
1163/*!
1164 \enum QAction::ActionEvent
1165
1166 This enum type is used when calling QAction::activate()
1167
1168 \value Trigger this will cause the QAction::triggered() signal to be emitted.
1169
1170 \value Hover this will cause the QAction::hovered() signal to be emitted.
1171*/
1172
1173/*!
1174 \property QAction::menuRole
1175 \brief the action's menu role
1176
1177 This indicates what role the action serves in the application menu on
1178 \macos. By default all actions have the TextHeuristicRole, which means that
1179 the action is added based on its text (see QMenuBar for more information).
1180
1181 The menu role can only be changed before the actions are put into the menu
1182 bar in \macos (usually just before the first application window is
1183 shown).
1184*/
1185void QAction::setMenuRole(MenuRole menuRole)
1186{
1187 Q_D(QAction);
1188 if (d->menuRole == menuRole)
1189 return;
1190
1191 d->menuRole = menuRole;
1192 d->sendDataChanged();
1193}
1194
1195QAction::MenuRole QAction::menuRole() const
1196{
1197 Q_D(const QAction);
1198 return d->menuRole;
1199}
1200
1201/*!
1202 \fn QMenu *QAction::menu() const
1203
1204 Returns the menu contained by this action.
1205
1206 In widget applications, actions that contain menus can be used to create menu
1207 items with submenus, or inserted into toolbars to create buttons with popup menus.
1208
1209 \sa QMenu::addAction(), QMenu::menuInAction()
1210*/
1211QObject* QAction::menuObject() const
1212{
1213 Q_D(const QAction);
1214 return d->menu();
1215}
1216
1217/*!
1218 \fn void QAction::setMenu(QMenu *menu)
1219
1220 Sets the menu contained by this action to the specified \a menu.
1221*/
1222void QAction::setMenuObject(QObject *object)
1223{
1224 Q_D(QAction);
1225 d->setMenu(object);
1226}
1227
1228/*!
1229 \property QAction::iconVisibleInMenu
1230 \brief Whether or not an action should show an icon in a menu
1231
1232 In some applications, it may make sense to have actions with icons in the
1233 toolbar, but not in menus. If true, the icon (if valid) is shown in the menu, when it
1234 is false, it is not shown.
1235
1236 The default is to follow whether the Qt::AA_DontShowIconsInMenus attribute
1237 is set for the application. Explicitly settings this property overrides
1238 the presence (or absence) of the attribute.
1239
1240 For example:
1241 \snippet code/src_gui_kernel_qaction.cpp 0
1242
1243 \sa icon, QCoreApplication::setAttribute()
1244*/
1245void QAction::setIconVisibleInMenu(bool visible)
1246{
1247 Q_D(QAction);
1248 if (d->iconVisibleInMenu == -1 || visible != bool(d->iconVisibleInMenu)) {
1249 int oldValue = d->iconVisibleInMenu;
1250 d->iconVisibleInMenu = visible;
1251 // Only send data changed if we really need to.
1252 if (oldValue != -1
1253 || visible == !QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus)) {
1254 d->sendDataChanged();
1255 }
1256 }
1257}
1258
1259bool QAction::isIconVisibleInMenu() const
1260{
1261 Q_D(const QAction);
1262 if (d->iconVisibleInMenu == -1) {
1263 return !QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus);
1264 }
1265 return d->iconVisibleInMenu;
1266}
1267
1268/*!
1269 \property QAction::shortcutVisibleInContextMenu
1270 \brief Whether or not an action should show a shortcut in a context menu
1271
1272 In some applications, it may make sense to have actions with shortcuts in
1273 context menus. If true, the shortcut (if valid) is shown when the action is
1274 shown via a context menu, when it is false, it is not shown.
1275
1276 The default is to follow whether the Qt::AA_DontShowShortcutsInContextMenus attribute
1277 is set for the application. Explicitly setting this property overrides the attribute.
1278
1279 \sa shortcut, QCoreApplication::setAttribute()
1280*/
1281void QAction::setShortcutVisibleInContextMenu(bool visible)
1282{
1283 Q_D(QAction);
1284 if (d->shortcutVisibleInContextMenu == -1 || visible != bool(d->shortcutVisibleInContextMenu)) {
1285 int oldValue = d->shortcutVisibleInContextMenu;
1286 d->shortcutVisibleInContextMenu = visible;
1287 // Only send data changed if we really need to.
1288 if (oldValue != -1
1289 || visible == !QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus)) {
1290 d->sendDataChanged();
1291 }
1292 }
1293}
1294
1295bool QAction::isShortcutVisibleInContextMenu() const
1296{
1297 Q_D(const QAction);
1298 if (d->shortcutVisibleInContextMenu == -1)
1299 return !QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus);
1300 return d->shortcutVisibleInContextMenu;
1301}
1302
1303#ifndef QT_NO_DEBUG_STREAM
1304Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAction *action)
1305{
1306 QDebugStateSaver saver(d);
1307 d.nospace();
1308 d << "QAction(" << static_cast<const void *>(action);
1309 if (action) {
1310 d << " text=" << action->text();
1311 if (!action->toolTip().isEmpty())
1312 d << " toolTip=" << action->toolTip();
1313 if (action->isCheckable())
1314 d << " checked=" << action->isChecked();
1315#if QT_CONFIG(shortcut)
1316 if (!action->shortcuts().isEmpty())
1317 d << " shortcuts=" << action->shortcuts();
1318#endif
1319 d << " menuRole=";
1320 QtDebugUtils::formatQEnum(d, action->menuRole());
1321 d << " enabled=" << action->isEnabled();
1322 d << " visible=" << action->isVisible();
1323 }
1324 d << ')';
1325 return d;
1326}
1327#endif // QT_NO_DEBUG_STREAM
1328
1329QT_END_NAMESPACE
1330
1331#undef QAPP_CHECK
1332
1333#include "moc_qaction.cpp"
Combined button and popup list for selecting options.
#define QAPP_CHECK(functionName)
Definition qaction.cpp:19
static QString qt_strippedText(QString s)
Definition qaction.cpp:32
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2582