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