00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qaction.h"
00025 #include "qactiongroup.h"
00026
00027 #ifndef QT_NO_ACTION
00028 #include "qaction_p.h"
00029 #include "qapplication.h"
00030 #include "qevent.h"
00031 #include "qlist.h"
00032 #include "qdebug.h"
00033 #include <private/qshortcutmap_p.h>
00034 #include <private/qapplication_p.h>
00035
00036
00037
00038
00039 static QString qt_strippedText(QString s)
00040 {
00041 s.remove( QString::fromLatin1("...") );
00042 int i = 0;
00043 while (i < s.size()) {
00044 ++i;
00045 if (s.at(i-1) != QLatin1Char('&'))
00046 continue;
00047 if (i < s.size() && s.at(i) == QLatin1Char('&'))
00048 ++i;
00049 s.remove(i-1,1);
00050 }
00051 return s.trimmed();
00052 };
00053
00054
00055 QActionPrivate::QActionPrivate() : group(0), enabled(1), forceDisabled(0),
00056 visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false),
00057 menuRole(QAction::TextHeuristicRole)
00058 {
00059 #ifdef QT3_SUPPORT
00060 static int qt_static_action_id = -1;
00061 param = id = --qt_static_action_id;
00062 act_signal = 0;
00063 #endif
00064 #ifndef QT_NO_SHORTCUT
00065 shortcutId = 0;
00066 shortcutContext = Qt::WindowShortcut;
00067 autorepeat = true;
00068 #endif
00069 }
00070
00071 QActionPrivate::~QActionPrivate()
00072 {
00073 }
00074
00075 void QActionPrivate::sendDataChanged()
00076 {
00077 Q_Q(QAction);
00078 QActionEvent e(QEvent::ActionChanged, q);
00079 for (int i = 0; i < widgets.size(); ++i) {
00080 QWidget *w = widgets.at(i);
00081 QApplication::sendEvent(w, &e);
00082 }
00083 QApplication::sendEvent(q, &e);
00084
00085 emit q->changed();
00086 }
00087
00088 #ifndef QT_NO_SHORTCUT
00089 void QActionPrivate::redoGrab(QShortcutMap &map)
00090 {
00091 Q_Q(QAction);
00092 if (shortcutId)
00093 map.removeShortcut(shortcutId, q);
00094 if (shortcut.isEmpty())
00095 return;
00096 shortcutId = map.addShortcut(q, shortcut, shortcutContext);
00097 if (!enabled)
00098 map.setShortcutEnabled(false, shortcutId, q);
00099 if (!autorepeat)
00100 map.setShortcutAutoRepeat(false, shortcutId, q);
00101 }
00102
00103 void QActionPrivate::redoGrabAlternate(QShortcutMap &map)
00104 {
00105 Q_Q(QAction);
00106 foreach (int id, alternateShortcutIds)
00107 if (id)
00108 map.removeShortcut(id, q);
00109 alternateShortcutIds.clear();
00110 if (alternateShortcuts.isEmpty())
00111 return;
00112 foreach (const QKeySequence& alternate, alternateShortcuts) {
00113 if (!alternate.isEmpty())
00114 alternateShortcutIds.append(map.addShortcut(q, alternate, shortcutContext));
00115 else
00116 alternateShortcutIds.append(0);
00117 }
00118 if (!enabled) {
00119 foreach (int id, alternateShortcutIds)
00120 map.setShortcutEnabled(false, id, q);
00121 }
00122 if (!autorepeat) {
00123 foreach (int id, alternateShortcutIds)
00124 map.setShortcutEnabled(false, id, q);
00125 }
00126 }
00127
00128 void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
00129 {
00130 Q_Q(QAction);
00131 if (shortcutId)
00132 map.setShortcutEnabled(enable, shortcutId, q);
00133 foreach (int id, alternateShortcutIds)
00134 if (id)
00135 map.setShortcutEnabled(enable, id, q);
00136 }
00137 #endif // QT_NO_SHORTCUT
00138
00227 QAction::QAction(QObject* parent)
00228 : QObject(*(new QActionPrivate), parent)
00229 {
00230 Q_D(QAction);
00231 d->group = qobject_cast<QActionGroup *>(parent);
00232 if (d->group)
00233 d->group->addAction(this);
00234 }
00235
00236
00250 QAction::QAction(const QString &text, QObject* parent)
00251 : QObject(*(new QActionPrivate), parent)
00252 {
00253 Q_D(QAction);
00254 d->text = text;
00255 d->group = qobject_cast<QActionGroup *>(parent);
00256 if (d->group)
00257 d->group->addAction(this);
00258 }
00259
00272 QAction::QAction(const QIcon &icon, const QString &text, QObject* parent)
00273 : QObject(*(new QActionPrivate), parent)
00274 {
00275 Q_D(QAction);
00276 d->icon = icon;
00277 d->text = text;
00278 d->group = qobject_cast<QActionGroup *>(parent);
00279 if (d->group)
00280 d->group->addAction(this);
00281 }
00282
00286 QAction::QAction(QActionPrivate &dd, QObject *parent)
00287 : QObject(dd, parent)
00288 {
00289 Q_D(QAction);
00290 d->group = qobject_cast<QActionGroup *>(parent);
00291 if (d->group)
00292 d->group->addAction(this);
00293 }
00294
00298 QWidget *QAction::parentWidget() const
00299 {
00300 QObject *ret = parent();
00301 while (ret && !ret->isWidgetType())
00302 ret = ret->parent();
00303 return (QWidget*)ret;
00304 }
00305
00312 QList<QWidget *> QAction::associatedWidgets() const
00313 {
00314 Q_D(const QAction);
00315 return d->widgets;
00316 }
00317
00318 #ifndef QT_NO_SHORTCUT
00319
00326 void QAction::setShortcut(const QKeySequence &shortcut)
00327 {
00328 Q_D(QAction);
00329 if (d->shortcut == shortcut)
00330 return;
00331
00332 d->shortcut = shortcut;
00333 d->redoGrab(qApp->d_func()->shortcutMap);
00334 d->sendDataChanged();
00335 }
00336
00345 void QAction::setShortcuts(const QList<QKeySequence> &shortcuts)
00346 {
00347 Q_D(QAction);
00348
00349 QList <QKeySequence> listCopy = shortcuts;
00350
00351 QKeySequence primary;
00352 if (!listCopy.isEmpty())
00353 primary = listCopy.takeFirst();
00354
00355 if (d->shortcut == primary && d->alternateShortcuts == listCopy)
00356 return;
00357
00358 d->shortcut = primary;
00359 d->alternateShortcuts = listCopy;
00360 d->redoGrab(qApp->d_func()->shortcutMap);
00361 d->redoGrabAlternate(qApp->d_func()->shortcutMap);
00362 d->sendDataChanged();
00363 }
00364
00375 void QAction::setShortcuts(QKeySequence::StandardKey key)
00376 {
00377 QList <QKeySequence> list = QKeySequence::keyBindings(key);
00378 setShortcuts(list);
00379 }
00380
00386 QKeySequence QAction::shortcut() const
00387 {
00388 Q_D(const QAction);
00389 return d->shortcut;
00390 }
00391
00400 QList<QKeySequence> QAction::shortcuts() const
00401 {
00402 Q_D(const QAction);
00403 QList <QKeySequence> shortcuts;
00404 if (!d->shortcut.isEmpty())
00405 shortcuts << d->shortcut;
00406 if (!d->alternateShortcuts.isEmpty())
00407 shortcuts << d->alternateShortcuts;
00408 return shortcuts;
00409 }
00410
00418 void QAction::setShortcutContext(Qt::ShortcutContext context)
00419 {
00420 Q_D(QAction);
00421 if (d->shortcutContext == context)
00422 return;
00423 d->shortcutContext = context;
00424 d->redoGrab(qApp->d_func()->shortcutMap);
00425 d->redoGrabAlternate(qApp->d_func()->shortcutMap);
00426 d->sendDataChanged();
00427 }
00428
00429 Qt::ShortcutContext QAction::shortcutContext() const
00430 {
00431 Q_D(const QAction);
00432 return d->shortcutContext;
00433 }
00434
00445 void QAction::setAutoRepeat(bool on)
00446 {
00447 Q_D(QAction);
00448 if (d->autorepeat == on)
00449 return;
00450 d->autorepeat = on;
00451 d->redoGrab(qApp->d_func()->shortcutMap);
00452 d->redoGrabAlternate(qApp->d_func()->shortcutMap);
00453 d->sendDataChanged();
00454 }
00455
00456 bool QAction::autoRepeat() const
00457 {
00458 Q_D(const QAction);
00459 return d->autorepeat;
00460 }
00461 #endif // QT_NO_SHORTCUT
00462
00473 void QAction::setFont(const QFont &font)
00474 {
00475 Q_D(QAction);
00476 if (d->font == font)
00477 return;
00478
00479 d->fontSet = true;
00480 d->font = font;
00481 d->sendDataChanged();
00482 }
00483
00484 QFont QAction::font() const
00485 {
00486 Q_D(const QAction);
00487 return d->font;
00488 }
00489
00490 #ifdef QT3_SUPPORT
00491
00495 QAction::QAction(QObject* parent, const char* name)
00496 : QObject(*(new QActionPrivate), parent)
00497 {
00498 Q_D(QAction);
00499 setObjectName(QString::fromAscii(name));
00500 d->group = qobject_cast<QActionGroup *>(parent);
00501 if (d->group)
00502 d->group->addAction(this);
00503 }
00504
00505
00510 QAction::QAction(const QString &text, const QKeySequence &shortcut, QObject* parent, const char* name)
00511 : QObject(*(new QActionPrivate), parent)
00512 {
00513 Q_D(QAction);
00514 setObjectName(QString::fromAscii(name));
00515 d->text = text;
00516 setShortcut(shortcut);
00517 d->group = qobject_cast<QActionGroup *>(parent);
00518 if (d->group)
00519 d->group->addAction(this);
00520 }
00521
00526 QAction::QAction(const QIcon &icon, const QString &text, const QKeySequence &shortcut,
00527 QObject* parent, const char* name)
00528 : QObject(*(new QActionPrivate), parent)
00529 {
00530 Q_D(QAction);
00531 setObjectName(QString::fromAscii(name));
00532 d->text = text;
00533 setShortcut(shortcut);
00534 d->icon = icon;
00535 d->group = qobject_cast<QActionGroup *>(parent);
00536 if (d->group)
00537 d->group->addAction(this);
00538 }
00539 #endif
00540
00544 QAction::~QAction()
00545 {
00546 Q_D(QAction);
00547 for (int i = d->widgets.size()-1; i >= 0; --i) {
00548 QWidget *w = d->widgets.at(i);
00549 w->removeAction(this);
00550 }
00551 if (d->group)
00552 d->group->removeAction(this);
00553 #ifndef QT_NO_SHORTCUT
00554 if (d->shortcutId && qApp)
00555 qApp->d_func()->shortcutMap.removeShortcut(d->shortcutId, this);
00556 #endif
00557 }
00558
00567 void QAction::setActionGroup(QActionGroup *group)
00568 {
00569 Q_D(QAction);
00570 if(group == d->group)
00571 return;
00572
00573 if(d->group)
00574 d->group->removeAction(this);
00575 d->group = group;
00576 if(group)
00577 group->addAction(this);
00578 }
00579
00586 QActionGroup *QAction::actionGroup() const
00587 {
00588 Q_D(const QAction);
00589 return d->group;
00590 }
00591
00592
00604 void QAction::setIcon(const QIcon &icon)
00605 {
00606 Q_D(QAction);
00607 d->icon = icon;
00608 d->sendDataChanged();
00609 }
00610
00611 QIcon QAction::icon() const
00612 {
00613 Q_D(const QAction);
00614 return d->icon;
00615 }
00616
00617 #ifndef QT_NO_MENU
00618
00625 QMenu *QAction::menu() const
00626 {
00627 Q_D(const QAction);
00628 return d->menu;
00629 }
00630
00634 void QAction::setMenu(QMenu *menu)
00635 {
00636 Q_D(QAction);
00637 d->menu = menu;
00638 d->sendDataChanged();
00639 }
00640 #endif // QT_NO_MENU
00641
00651 void QAction::setSeparator(bool b)
00652 {
00653 Q_D(QAction);
00654 if (d->separator == b)
00655 return;
00656
00657 d->separator = b;
00658 d->sendDataChanged();
00659 }
00660
00667 bool QAction::isSeparator() const
00668 {
00669 Q_D(const QAction);
00670 return d->separator;
00671 }
00672
00685 void QAction::setText(const QString &text)
00686 {
00687 Q_D(QAction);
00688 if (d->text == text)
00689 return;
00690
00691 d->text = text;
00692 d->sendDataChanged();
00693 }
00694
00695 QString QAction::text() const
00696 {
00697 Q_D(const QAction);
00698 QString s = d->text;
00699 if(s.isEmpty()) {
00700 s = d->iconText;
00701 s.replace(QLatin1Char('&'), QLatin1String("&&"));
00702 }
00703 return s;
00704 }
00705
00706
00707
00708
00709
00729 void QAction::setIconText(const QString &text)
00730 {
00731 Q_D(QAction);
00732 if (d->iconText == text)
00733 return;
00734
00735 d->iconText = text;
00736 d->sendDataChanged();
00737 }
00738
00739 QString QAction::iconText() const
00740 {
00741 Q_D(const QAction);
00742 if (d->iconText.isEmpty())
00743 return qt_strippedText(d->text);
00744 return d->iconText;
00745 }
00746
00747
00748
00758 void QAction::setToolTip(const QString &tooltip)
00759 {
00760 Q_D(QAction);
00761 if (d->tooltip == tooltip)
00762 return;
00763
00764 d->tooltip = tooltip;
00765 d->sendDataChanged();
00766 }
00767
00768 QString QAction::toolTip() const
00769 {
00770 Q_D(const QAction);
00771 if (d->tooltip.isEmpty()) {
00772 if (!d->text.isEmpty())
00773 return qt_strippedText(d->text);
00774 return d->iconText;
00775 }
00776 return d->tooltip;
00777 }
00778
00788 void QAction::setStatusTip(const QString &statustip)
00789 {
00790 Q_D(QAction);
00791 if (d->statustip == statustip)
00792 return;
00793
00794 d->statustip = statustip;
00795 d->sendDataChanged();
00796 }
00797
00798 QString QAction::statusTip() const
00799 {
00800 Q_D(const QAction);
00801 return d->statustip;
00802 }
00803
00814 void QAction::setWhatsThis(const QString &whatsthis)
00815 {
00816 Q_D(QAction);
00817 if (d->whatsthis == whatsthis)
00818 return;
00819
00820 d->whatsthis = whatsthis;
00821 d->sendDataChanged();
00822 }
00823
00824 QString QAction::whatsThis() const
00825 {
00826 Q_D(const QAction);
00827 return d->whatsthis;
00828 }
00829
00830
00850 void QAction::setCheckable(bool b)
00851 {
00852 Q_D(QAction);
00853 if (d->checkable == b)
00854 return;
00855
00856 d->checkable = b;
00857 d->checked = false;
00858 d->sendDataChanged();
00859 }
00860
00861 bool QAction::isCheckable() const
00862 {
00863 Q_D(const QAction);
00864 return d->checkable;
00865 }
00866
00873 void QAction::toggle()
00874 {
00875 Q_D(QAction);
00876 setChecked(!d->checked);
00877 }
00878
00888 void QAction::setChecked(bool b)
00889 {
00890 Q_D(QAction);
00891 if (!d->checkable || d->checked == b)
00892 return;
00893
00894 QPointer<QAction> guard(this);
00895 d->checked = b;
00896 d->sendDataChanged();
00897 if (guard)
00898 emit toggled(b);
00899 }
00900
00901 bool QAction::isChecked() const
00902 {
00903 Q_D(const QAction);
00904 return d->checked;
00905 }
00906
00927 void QAction::setEnabled(bool b)
00928 {
00929 Q_D(QAction);
00930 if (b == d->enabled && b != d->forceDisabled)
00931 return;
00932 d->forceDisabled = !b;
00933 if (b && d->group && !d->group->isEnabled())
00934 return;
00935 d->enabled = b;
00936 #ifndef QT_NO_SHORTCUT
00937 d->setShortcutEnabled(b, qApp->d_func()->shortcutMap);
00938 #endif
00939 d->sendDataChanged();
00940 }
00941
00942 bool QAction::isEnabled() const
00943 {
00944 Q_D(const QAction);
00945 return d->enabled;
00946 }
00947
00959 void QAction::setVisible(bool b)
00960 {
00961 Q_D(QAction);
00962 if (b == d->visible && b != d->forceInvisible)
00963 return;
00964 d->forceInvisible = !b;
00965 d->visible = b;
00966 d->sendDataChanged();
00967 }
00968
00969
00970 bool QAction::isVisible() const
00971 {
00972 Q_D(const QAction);
00973 return d->visible;
00974 }
00975
00979 bool
00980 QAction::event(QEvent *e)
00981 {
00982 #ifndef QT_NO_SHORTCUT
00983 if (e->type() == QEvent::Shortcut) {
00984 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
00985 Q_ASSERT_X(se->key() == d_func()->shortcut || d_func()->alternateShortcuts.contains(se->key()),
00986 "QAction::event",
00987 "Received shortcut event from incorrect shortcut");
00988 if (se->isAmbiguous())
00989 qWarning("QAction::eventFilter: Ambiguous shortcut overload: %s", QString(se->key()).toLatin1().constData());
00990 else
00991 activate(Trigger);
00992 return true;
00993 }
00994 #endif
00995 return QObject::event(e);
00996 }
00997
01003 QVariant
01004 QAction::data() const
01005 {
01006 Q_D(const QAction);
01007 return d->userData;
01008 }
01009
01017 void
01018 QAction::setData(const QVariant &data)
01019 {
01020 Q_D(QAction);
01021 d->userData = data;
01022 d->sendDataChanged();
01023 }
01024
01025
01033 bool
01034 QAction::showStatusText(QWidget *widget)
01035 {
01036 #ifdef QT_NO_STATUSTIP
01037 Q_UNUSED(widget);
01038 #else
01039 if(QObject *object = widget ? widget : parent()) {
01040 QStatusTipEvent tip(statusTip());
01041 QApplication::sendEvent(object, &tip);
01042 return true;
01043 }
01044 #endif
01045 return false;
01046 }
01047
01054 void QAction::activate(ActionEvent event)
01055 {
01056 Q_D(QAction);
01057 if(event == Trigger) {
01058 QObject *guard = this;
01059 QMetaObject::addGuard(&guard);
01060 if(d->checkable) {
01061
01062 if (d->checked && (d->group && d->group->isExclusive()
01063 && d->group->checkedAction() == this)) {
01064 QMetaObject::removeGuard(&guard);
01065 return;
01066 }
01067 setChecked(!d->checked);
01068 }
01069 if (guard)
01070 emit triggered(d->checked);
01071 #ifdef QT3_SUPPORT
01072 if (guard)
01073 emit activated(d->param);
01074 #endif
01075 QMetaObject::removeGuard(&guard);
01076 } else if(event == Hover) {
01077 emit hovered();
01078 }
01079 }
01080
01244 void QAction::setMenuRole(MenuRole menuRole)
01245 {
01246 Q_D(QAction);
01247 if (d->menuRole == menuRole)
01248 return;
01249
01250 d->menuRole = menuRole;
01251 d->sendDataChanged();
01252 }
01253
01254 QAction::MenuRole QAction::menuRole() const
01255 {
01256 Q_D(const QAction);
01257 return d->menuRole;
01258 }
01259
01260 #include "moc_qaction.cpp"
01261 #endif // QT_NO_ACTION
01262