61be508d396c604893d340ca3771e3aa59928b5d
[profile/ivi/qtbase.git] / src / widgets / kernel / qaction.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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);
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));
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 examples/mainwindows/application/mainwindow.cpp 19
239     \codeline
240     \snippet examples/mainwindows/application/mainwindow.cpp 28
241     \snippet examples/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     On Symbian the icons which are passed to softkeys, i.e. to actions with
666     softkey role, need to have pixmap alpha channel correctly set otherwise
667     drawing artifacts will appear when softkey is pressed down.
668
669     If a null icon (QIcon::isNull() is passed into this function,
670     the icon of the action is cleared.
671 */
672 void QAction::setIcon(const QIcon &icon)
673 {
674     Q_D(QAction);
675     d->icon = icon;
676     d->sendDataChanged();
677 }
678
679 QIcon QAction::icon() const
680 {
681     Q_D(const QAction);
682     return d->icon;
683 }
684
685 #ifndef QT_NO_MENU
686 /*!
687   Returns the menu contained by this action. Actions that contain
688   menus can be used to create menu items with submenus, or inserted
689   into toolbars to create buttons with popup menus.
690
691   \sa QMenu::addAction()
692 */
693 QMenu *QAction::menu() const
694 {
695     Q_D(const QAction);
696     return d->menu;
697 }
698
699 /*!
700     Sets the menu contained by this action to the specified \a menu.
701 */
702 void QAction::setMenu(QMenu *menu)
703 {
704     Q_D(QAction);
705     if (d->menu)
706         d->menu->d_func()->setOverrideMenuAction(0); //we reset the default action of any previous menu
707     d->menu = menu;
708     if (menu)
709         menu->d_func()->setOverrideMenuAction(this);
710     d->sendDataChanged();
711 }
712 #endif // QT_NO_MENU
713
714 /*!
715   If \a b is true then this action will be considered a separator.
716
717   How a separator is represented depends on the widget it is inserted
718   into. Under most circumstances the text, submenu, and icon will be
719   ignored for separator actions.
720
721   \sa QAction::isSeparator()
722 */
723 void QAction::setSeparator(bool b)
724 {
725     Q_D(QAction);
726     if (d->separator == b)
727         return;
728
729     d->separator = b;
730     d->sendDataChanged();
731 }
732
733 /*!
734   Returns true if this action is a separator action; otherwise it
735   returns false.
736
737   \sa QAction::setSeparator()
738 */
739 bool QAction::isSeparator() const
740 {
741     Q_D(const QAction);
742     return d->separator;
743 }
744
745 /*!
746     \property QAction::text
747     \brief the action's descriptive text
748
749     If the action is added to a menu, the menu option will consist of
750     the icon (if there is one), the text, and the shortcut (if there
751     is one). If the text is not explicitly set in the constructor, or
752     by using setText(), the action's description icon text will be
753     used as text. There is no default text.
754
755     \sa iconText
756 */
757 void QAction::setText(const QString &text)
758 {
759     Q_D(QAction);
760     if (d->text == text)
761         return;
762
763     d->text = text;
764     d->sendDataChanged();
765 }
766
767 QString QAction::text() const
768 {
769     Q_D(const QAction);
770     QString s = d->text;
771     if(s.isEmpty()) {
772         s = d->iconText;
773         s.replace(QLatin1Char('&'), QLatin1String("&&"));
774     }
775     return s;
776 }
777
778
779
780
781
782 /*!
783     \property QAction::iconText
784     \brief the action's descriptive icon text
785
786     If QToolBar::toolButtonStyle is set to a value that permits text to
787     be displayed, the text defined held in this property appears as a
788     label in the relevant tool button.
789
790     It also serves as the default text in menus and tooltips if the action
791     has not been defined with setText() or setToolTip(), and will
792     also be used in toolbar buttons if no icon has been defined using setIcon().
793
794     If the icon text is not explicitly set, the action's normal text will be
795     used for the icon text.
796
797     By default, this property contains an empty string.
798
799     \sa setToolTip(), setStatusTip()
800 */
801 void QAction::setIconText(const QString &text)
802 {
803     Q_D(QAction);
804     if (d->iconText == text)
805         return;
806
807     d->iconText = text;
808     d->sendDataChanged();
809 }
810
811 QString QAction::iconText() const
812 {
813     Q_D(const QAction);
814     if (d->iconText.isEmpty())
815         return qt_strippedText(d->text);
816     return d->iconText;
817 }
818
819 /*!
820     \property QAction::toolTip
821     \brief the action's tooltip
822
823     This text is used for the tooltip. If no tooltip is specified,
824     the action's text is used.
825
826     By default, this property contains the action's text.
827
828     \sa setStatusTip() setShortcut()
829 */
830 void QAction::setToolTip(const QString &tooltip)
831 {
832     Q_D(QAction);
833     if (d->tooltip == tooltip)
834         return;
835
836     d->tooltip = tooltip;
837     d->sendDataChanged();
838 }
839
840 QString QAction::toolTip() const
841 {
842     Q_D(const QAction);
843     if (d->tooltip.isEmpty()) {
844         if (!d->text.isEmpty())
845             return qt_strippedText(d->text);
846         return qt_strippedText(d->iconText);
847     }
848     return d->tooltip;
849 }
850
851 /*!
852     \property QAction::statusTip
853     \brief the action's status tip
854
855     The status tip is displayed on all status bars provided by the
856     action's top-level parent widget.
857
858     By default, this property contains an empty string.
859
860     \sa setToolTip() showStatusText()
861 */
862 void QAction::setStatusTip(const QString &statustip)
863 {
864     Q_D(QAction);
865     if (d->statustip == statustip)
866         return;
867
868     d->statustip = statustip;
869     d->sendDataChanged();
870 }
871
872 QString QAction::statusTip() const
873 {
874     Q_D(const QAction);
875     return d->statustip;
876 }
877
878 /*!
879     \property QAction::whatsThis
880     \brief the action's "What's This?" help text
881
882     The "What's This?" text is used to provide a brief description of
883     the action. The text may contain rich text. There is no default
884     "What's This?" text.
885
886     \sa QWhatsThis Q3StyleSheet
887 */
888 void QAction::setWhatsThis(const QString &whatsthis)
889 {
890     Q_D(QAction);
891     if (d->whatsthis == whatsthis)
892         return;
893
894     d->whatsthis = whatsthis;
895     d->sendDataChanged();
896 }
897
898 QString QAction::whatsThis() const
899 {
900     Q_D(const QAction);
901     return d->whatsthis;
902 }
903
904 /*!
905     \enum QAction::Priority
906     \since 4.6
907
908     This enum defines priorities for actions in user interface.
909
910     \value LowPriority The action should not be prioritized in
911     the user interface.
912
913     \value NormalPriority
914
915     \value HighPriority The action should be prioritized in
916     the user interface.
917
918     \sa priority
919 */
920
921
922 /*!
923     \property QAction::priority
924     \since 4.6
925
926     \brief the actions's priority in the user interface.
927
928     This property can be set to indicate how the action should be prioritized
929     in the user interface.
930
931     For instance, when toolbars have the Qt::ToolButtonTextBesideIcon
932     mode set, then actions with LowPriority will not show the text
933     labels.
934 */
935 void QAction::setPriority(Priority priority)
936 {
937     Q_D(QAction);
938     if (d->priority == priority)
939         return;
940
941     d->priority = priority;
942     d->sendDataChanged();
943 }
944
945 QAction::Priority QAction::priority() const
946 {
947     Q_D(const QAction);
948     return d->priority;
949 }
950
951 /*!
952     \property QAction::checkable
953     \brief whether the action is a checkable action
954
955     A checkable action is one which has an on/off state. For example,
956     in a word processor, a Bold toolbar button may be either on or
957     off. An action which is not a toggle action is a command action;
958     a command action is simply executed, e.g. file save.
959     By default, this property is false.
960
961     In some situations, the state of one toggle action should depend
962     on the state of others. For example, "Left Align", "Center" and
963     "Right Align" toggle actions are mutually exclusive. To achieve
964     exclusive toggling, add the relevant toggle actions to a
965     QActionGroup with the QActionGroup::exclusive property set to
966     true.
967
968     \sa QAction::setChecked()
969 */
970 void QAction::setCheckable(bool b)
971 {
972     Q_D(QAction);
973     if (d->checkable == b)
974         return;
975
976     d->checkable = b;
977     d->checked = false;
978     d->sendDataChanged();
979 }
980
981 bool QAction::isCheckable() const
982 {
983     Q_D(const QAction);
984     return d->checkable;
985 }
986
987 /*!
988     \fn void QAction::toggle()
989
990     This is a convenience function for the \l checked property.
991     Connect to it to change the checked state to its opposite state.
992 */
993 void QAction::toggle()
994 {
995     Q_D(QAction);
996     setChecked(!d->checked);
997 }
998
999 /*!
1000     \property QAction::checked
1001     \brief whether the action is checked.
1002
1003     Only checkable actions can be checked.  By default, this is false
1004     (the action is unchecked).
1005
1006     \sa checkable
1007 */
1008 void QAction::setChecked(bool b)
1009 {
1010     Q_D(QAction);
1011     if (!d->checkable || d->checked == b)
1012         return;
1013
1014     QPointer<QAction> guard(this);
1015     d->checked = b;
1016     d->sendDataChanged();
1017     if (guard)
1018         emit toggled(b);
1019 }
1020
1021 bool QAction::isChecked() const
1022 {
1023     Q_D(const QAction);
1024     return d->checked;
1025 }
1026
1027 /*!
1028     \fn void QAction::setDisabled(bool b)
1029
1030     This is a convenience function for the \l enabled property, that
1031     is useful for signals--slots connections. If \a b is true the
1032     action is disabled; otherwise it is enabled.
1033 */
1034
1035 /*!
1036     \property QAction::enabled
1037     \brief whether the action is enabled
1038
1039     Disabled actions cannot be chosen by the user. They do not
1040     disappear from menus or toolbars, but they are displayed in a way
1041     which indicates that they are unavailable. For example, they might
1042     be displayed using only shades of gray.
1043
1044     \gui{What's This?} help on disabled actions is still available, provided
1045     that the QAction::whatsThis property is set.
1046
1047     An action will be disabled when all widgets to which it is added
1048     (with QWidget::addAction()) are disabled or not visible. When an
1049     action is disabled, it is not possible to trigger it through its
1050     shortcut.
1051
1052     By default, this property is true (actions are enabled).
1053
1054     \sa text
1055 */
1056 void QAction::setEnabled(bool b)
1057 {
1058     Q_D(QAction);
1059     if (b == d->enabled && b != d->forceDisabled)
1060         return;
1061     d->forceDisabled = !b;
1062     if (b && (!d->visible || (d->group && !d->group->isEnabled())))
1063         return;
1064     QAPP_CHECK("setEnabled");
1065     d->enabled = b;
1066 #ifndef QT_NO_SHORTCUT
1067     d->setShortcutEnabled(b, qApp->d_func()->shortcutMap);
1068 #endif
1069     d->sendDataChanged();
1070 }
1071
1072 bool QAction::isEnabled() const
1073 {
1074     Q_D(const QAction);
1075     return d->enabled;
1076 }
1077
1078 /*!
1079     \property QAction::visible
1080     \brief whether the action can be seen (e.g. in menus and toolbars)
1081
1082     If \e visible is true the action can be seen (e.g. in menus and
1083     toolbars) and chosen by the user; if \e visible is false the
1084     action cannot be seen or chosen by the user.
1085
1086     Actions which are not visible are \e not grayed out; they do not
1087     appear at all.
1088
1089     By default, this property is true (actions are visible).
1090 */
1091 void QAction::setVisible(bool b)
1092 {
1093     Q_D(QAction);
1094     if (b == d->visible && b != d->forceInvisible)
1095         return;
1096     QAPP_CHECK("setVisible");
1097     d->forceInvisible = !b;
1098     d->visible = b;
1099     d->enabled = b && !d->forceDisabled && (!d->group || d->group->isEnabled()) ;
1100 #ifndef QT_NO_SHORTCUT
1101     d->setShortcutEnabled(d->enabled, qApp->d_func()->shortcutMap);
1102 #endif
1103     d->sendDataChanged();
1104 }
1105
1106
1107 bool QAction::isVisible() const
1108 {
1109     Q_D(const QAction);
1110     return d->visible;
1111 }
1112
1113 /*!
1114   \reimp
1115 */
1116 bool
1117 QAction::event(QEvent *e)
1118 {
1119 #ifndef QT_NO_SHORTCUT
1120     if (e->type() == QEvent::Shortcut) {
1121         QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
1122         Q_ASSERT_X(se->key() == d_func()->shortcut || d_func()->alternateShortcuts.contains(se->key()),
1123                    "QAction::event",
1124                    "Received shortcut event from incorrect shortcut");
1125         if (se->isAmbiguous())
1126             qWarning("QAction::eventFilter: Ambiguous shortcut overload: %s", QString(se->key()).toLatin1().constData());
1127         else
1128             activate(Trigger);
1129         return true;
1130     }
1131 #endif
1132     return QObject::event(e);
1133 }
1134
1135 /*!
1136   Returns the user data as set in QAction::setData.
1137
1138   \sa setData()
1139 */
1140 QVariant
1141 QAction::data() const
1142 {
1143     Q_D(const QAction);
1144     return d->userData;
1145 }
1146
1147 /*!
1148   \fn void QAction::setData(const QVariant &userData)
1149
1150   Sets the action's internal data to the given \a userData.
1151
1152   \sa data()
1153 */
1154 void
1155 QAction::setData(const QVariant &data)
1156 {
1157     Q_D(QAction);
1158     d->userData = data;
1159     d->sendDataChanged();
1160 }
1161
1162
1163 /*!
1164   Updates the relevant status bar for the \a widget specified by sending a
1165   QStatusTipEvent to its parent widget. Returns true if an event was sent;
1166   otherwise returns false.
1167
1168   If a null widget is specified, the event is sent to the action's parent.
1169
1170   \sa statusTip
1171 */
1172 bool
1173 QAction::showStatusText(QWidget *widget)
1174 {
1175     return d_func()->showStatusText(widget, statusTip());
1176 }
1177
1178 /*!
1179   Sends the relevant signals for ActionEvent \a event.
1180
1181   Action based widgets use this API to cause the QAction
1182   to emit signals as well as emitting their own.
1183 */
1184 void QAction::activate(ActionEvent event)
1185 {
1186     Q_D(QAction);
1187     if(event == Trigger) {
1188         QObject *guard = this;
1189         QMetaObject::addGuard(&guard);
1190         if(d->checkable) {
1191             // the checked action of an exclusive group cannot be  unchecked
1192             if (d->checked && (d->group && d->group->isExclusive()
1193                                && d->group->checkedAction() == this)) {
1194                 if (guard)
1195                     emit triggered(true);
1196                 QMetaObject::removeGuard(&guard);
1197                 return;
1198             }
1199             setChecked(!d->checked);
1200         }
1201         if (guard)
1202             emit triggered(d->checked);
1203         QMetaObject::removeGuard(&guard);
1204     } else if(event == Hover) {
1205         emit hovered();
1206     }
1207 }
1208
1209 /*!
1210     \fn void QAction::triggered(bool checked)
1211
1212     This signal is emitted when an action is activated by the user;
1213     for example, when the user clicks a menu option, toolbar button,
1214     or presses an action's shortcut key combination, or when trigger()
1215     was called. Notably, it is \e not emitted when setChecked() or
1216     toggle() is called.
1217
1218     If the action is checkable, \a checked is true if the action is
1219     checked, or false if the action is unchecked.
1220
1221     \sa QAction::activate(), QAction::toggled(), checked
1222 */
1223
1224 /*!
1225     \fn void QAction::toggled(bool checked)
1226
1227     This signal is emitted whenever a checkable action changes its
1228     isChecked() status. This can be the result of a user interaction,
1229     or because setChecked() was called.
1230
1231     \a checked is true if the action is checked, or false if the
1232     action is unchecked.
1233
1234     \sa QAction::activate(), QAction::triggered(), checked
1235 */
1236
1237 /*!
1238     \fn void QAction::hovered()
1239
1240     This signal is emitted when an action is highlighted by the user;
1241     for example, when the user pauses with the cursor over a menu option,
1242     toolbar button, or presses an action's shortcut key combination.
1243
1244     \sa QAction::activate()
1245 */
1246
1247 /*!
1248     \fn void QAction::changed()
1249
1250     This signal is emitted when an action has changed. If you
1251     are only interested in actions in a given widget, you can
1252     watch for QWidget::actionEvent() sent with an
1253     QEvent::ActionChanged.
1254
1255     \sa QWidget::actionEvent()
1256 */
1257
1258 /*!
1259     \enum QAction::ActionEvent
1260
1261     This enum type is used when calling QAction::activate()
1262
1263     \value Trigger this will cause the QAction::triggered() signal to be emitted.
1264
1265     \value Hover this will cause the QAction::hovered() signal to be emitted.
1266 */
1267
1268 /*!
1269     \fn void QAction::setMenuText(const QString &text)
1270
1271     Use setText() instead.
1272 */
1273
1274 /*!
1275     \fn QString QAction::menuText() const
1276
1277     Use text() instead.
1278 */
1279
1280 /*!
1281     \fn bool QAction::isOn() const
1282
1283     Use isChecked() instead.
1284 */
1285
1286 /*!
1287     \fn void QAction::setOn(bool b)
1288
1289     Use setChecked() instead.
1290 */
1291
1292 /*!
1293     \fn bool QAction::isToggleAction() const
1294
1295     Use isCheckable() instead.
1296 */
1297
1298 /*!
1299     \fn void QAction::setToggleAction(bool b)
1300
1301     Use setCheckable() instead.
1302 */
1303
1304 /*!
1305     \fn void QAction::setIconSet(const QIcon &i)
1306
1307     Use setIcon() instead.
1308 */
1309
1310 /*!
1311     \fn bool QAction::addTo(QWidget *w)
1312
1313     Use QWidget::addAction() instead.
1314
1315     \oldcode
1316     action->addTo(widget);
1317     \newcode
1318     widget->addAction(action);
1319     \endcode
1320 */
1321
1322 /*!
1323     \fn bool QAction::removeFrom(QWidget *w)
1324
1325     Use QWidget::removeAction() instead.
1326
1327     \oldcode
1328     action->removeFrom(widget);
1329     \newcode
1330     widget->removeAction(action);
1331     \endcode
1332 */
1333
1334 /*!
1335     \fn void QAction::setAccel(const QKeySequence &shortcut)
1336
1337     Use setShortcut() instead.
1338 */
1339
1340 /*!
1341     \fn QIcon QAction::iconSet() const
1342
1343     Use icon() instead.
1344 */
1345
1346 /*!
1347     \fn QKeySequence QAction::accel() const
1348
1349     Use shortcut() instead.
1350 */
1351
1352 /*!
1353     \fn void QAction::activated(int i);
1354
1355     Use triggered() instead.
1356 */
1357
1358
1359 /*!
1360     \property QAction::menuRole
1361     \brief the action's menu role
1362     \since 4.2
1363
1364     This indicates what role the action serves in the application menu on Mac
1365     OS X. By default all action have the TextHeuristicRole, which means that
1366     the action is added based on its text (see QMenuBar for more information).
1367
1368     The menu role can only be changed before the actions are put into the menu
1369     bar in Mac OS X (usually just before the first application window is
1370     shown).
1371 */
1372 void QAction::setMenuRole(MenuRole menuRole)
1373 {
1374     Q_D(QAction);
1375     if (d->menuRole == menuRole)
1376         return;
1377
1378     d->menuRole = menuRole;
1379     d->sendDataChanged();
1380 }
1381
1382 QAction::MenuRole QAction::menuRole() const
1383 {
1384     Q_D(const QAction);
1385     return d->menuRole;
1386 }
1387
1388 /*!
1389     \property QAction::softKeyRole
1390     \brief the action's softkey role
1391     \since 4.6
1392
1393     This indicates what type of role this action describes in the softkey framework
1394     on platforms where such a framework is supported. Currently this is only
1395     supported on the Symbian platform.
1396
1397     The softkey role can be changed any time.
1398 */
1399 void QAction::setSoftKeyRole(SoftKeyRole softKeyRole)
1400 {
1401     Q_D(QAction);
1402     if (d->softKeyRole == softKeyRole)
1403         return;
1404
1405     d->softKeyRole = softKeyRole;
1406     d->sendDataChanged();
1407 }
1408
1409 QAction::SoftKeyRole QAction::softKeyRole() const
1410 {
1411     Q_D(const QAction);
1412     return d->softKeyRole;
1413 }
1414
1415 /*!
1416     \property QAction::iconVisibleInMenu
1417     \brief Whether or not an action should show an icon in a menu
1418     \since 4.4
1419
1420     In some applications, it may make sense to have actions with icons in the
1421     toolbar, but not in menus. If true, the icon (if valid) is shown in the menu, when it
1422     is false, it is not shown.
1423
1424     The default is to follow whether the Qt::AA_DontShowIconsInMenus attribute
1425     is set for the application. Explicitly settings this property overrides
1426     the presence (or abscence) of the attribute.
1427
1428     For example:
1429     \snippet doc/src/snippets/code/src_gui_kernel_qaction.cpp 0
1430
1431     \sa QAction::icon QApplication::setAttribute()
1432 */
1433 void QAction::setIconVisibleInMenu(bool visible)
1434 {
1435     Q_D(QAction);
1436     if (d->iconVisibleInMenu == -1 || visible != bool(d->iconVisibleInMenu)) {
1437         int oldValue = d->iconVisibleInMenu;
1438         d->iconVisibleInMenu = visible;
1439         // Only send data changed if we really need to.
1440         if (oldValue != -1
1441             || (oldValue == -1
1442                 && visible == !QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus))) {
1443             d->sendDataChanged();
1444         }
1445     }
1446 }
1447
1448 bool QAction::isIconVisibleInMenu() const
1449 {
1450     Q_D(const QAction);
1451     if (d->iconVisibleInMenu == -1) {
1452         return !QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus);
1453     }
1454     return d->iconVisibleInMenu;
1455 }
1456
1457 QT_END_NAMESPACE
1458
1459 #include "moc_qaction.cpp"
1460
1461 #endif // QT_NO_ACTION