src/gui/kernel/qaction.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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   internal: guesses a descriptive text from a text suited for a menu entry
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             // the checked action of an exclusive group cannot be  unchecked
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 

Generated on Thu Mar 15 11:55:01 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1