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