src/gui/kernel/qactiongroup.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qactiongroup.h"
       
    43 
       
    44 #ifndef QT_NO_ACTION
       
    45 
       
    46 #include "qaction_p.h"
       
    47 #include "qapplication.h"
       
    48 #include "qevent.h"
       
    49 #include "qlist.h"
       
    50 
       
    51 QT_BEGIN_NAMESPACE
       
    52 
       
    53 class QActionGroupPrivate : public QObjectPrivate
       
    54 {
       
    55     Q_DECLARE_PUBLIC(QActionGroup)
       
    56 public:
       
    57     QActionGroupPrivate() : exclusive(1), enabled(1), visible(1)  { }
       
    58     QList<QAction *> actions;
       
    59     QPointer<QAction> current;
       
    60     uint exclusive : 1;
       
    61     uint enabled : 1;
       
    62     uint visible : 1;
       
    63 
       
    64 private:
       
    65     void _q_actionTriggered();  //private slot
       
    66     void _q_actionChanged();    //private slot
       
    67     void _q_actionHovered();    //private slot
       
    68 };
       
    69 
       
    70 void QActionGroupPrivate::_q_actionChanged()
       
    71 {
       
    72     Q_Q(QActionGroup);
       
    73     QAction *action = qobject_cast<QAction*>(q->sender());
       
    74     Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error");
       
    75     if(exclusive && action->isChecked() && action != current) {
       
    76         if(current)
       
    77             current->setChecked(false);
       
    78         current = action;
       
    79     }
       
    80 }
       
    81 
       
    82 void QActionGroupPrivate::_q_actionTriggered()
       
    83 {
       
    84     Q_Q(QActionGroup);
       
    85     QAction *action = qobject_cast<QAction*>(q->sender());
       
    86     Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionTriggered", "internal error");
       
    87     emit q->triggered(action);
       
    88     emit q->selected(action);
       
    89 }
       
    90 
       
    91 void QActionGroupPrivate::_q_actionHovered()
       
    92 {
       
    93     Q_Q(QActionGroup);
       
    94     QAction *action = qobject_cast<QAction*>(q->sender());
       
    95     Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionHovered", "internal error");
       
    96     emit q->hovered(action);
       
    97 }
       
    98 
       
    99 /*!
       
   100     \class QActionGroup
       
   101     \brief The QActionGroup class groups actions together.
       
   102 
       
   103     \ingroup mainwindow-classes
       
   104 
       
   105     In some situations it is useful to group actions together. For
       
   106     example, if you have a \gui{Left Align} action, a \gui{Right
       
   107     Align} action, a \gui{Justify} action, and a \gui{Center} action,
       
   108     only one of these actions should be active at any one time. One
       
   109     simple way of achieving this is to group the actions together in
       
   110     an action group.
       
   111 
       
   112     Here's a example (from the \l{mainwindows/menus}{Menus} example):
       
   113 
       
   114     \snippet examples/mainwindows/menus/mainwindow.cpp 6
       
   115 
       
   116     Here we create a new action group. Since the action group is
       
   117     exclusive by default, only one of the actions in the group is
       
   118     checked at any one time.
       
   119 
       
   120     \img qactiongroup-align.png Alignment options in a QMenu
       
   121 
       
   122     A QActionGroup emits an triggered() signal when one of its
       
   123     actions is chosen. Each action in an action group emits its
       
   124     triggered() signal as usual.
       
   125 
       
   126     As stated above, an action group is \l exclusive by default; it
       
   127     ensures that only one checkable action is active at any one time.
       
   128     If you want to group checkable actions without making them
       
   129     exclusive, you can turn of exclusiveness by calling
       
   130     setExclusive(false).
       
   131 
       
   132     Actions can be added to an action group using addAction(), but it
       
   133     is usually more convenient to specify a group when creating
       
   134     actions; this ensures that actions are automatically created with
       
   135     a parent. Actions can be visually separated from each other by
       
   136     adding a separator action to the group; create an action and use
       
   137     QAction's \l {QAction::}{setSeparator()} function to make it
       
   138     considered a separator. Action groups are added to widgets with
       
   139     the QWidget::addActions() function.
       
   140 
       
   141     \sa QAction
       
   142 */
       
   143 
       
   144 /*!
       
   145     Constructs an action group for the \a parent object.
       
   146 
       
   147     The action group is exclusive by default. Call setExclusive(false)
       
   148     to make the action group non-exclusive.
       
   149 */
       
   150 QActionGroup::QActionGroup(QObject* parent) : QObject(*new QActionGroupPrivate, parent)
       
   151 {
       
   152 }
       
   153 
       
   154 /*!
       
   155     Destroys the action group.
       
   156 */
       
   157 QActionGroup::~QActionGroup()
       
   158 {
       
   159 }
       
   160 
       
   161 /*!
       
   162     \fn QAction *QActionGroup::addAction(QAction *action)
       
   163 
       
   164     Adds the \a action to this group, and returns it.
       
   165 
       
   166     Normally an action is added to a group by creating it with the
       
   167     group as its parent, so this function is not usually used.
       
   168 
       
   169     \sa QAction::setActionGroup()
       
   170 */
       
   171 QAction *QActionGroup::addAction(QAction* a)
       
   172 {
       
   173     Q_D(QActionGroup);
       
   174     if(!d->actions.contains(a)) {
       
   175         d->actions.append(a);
       
   176         QObject::connect(a, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
       
   177         QObject::connect(a, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
       
   178         QObject::connect(a, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
       
   179     }
       
   180     if(!a->d_func()->forceDisabled) {
       
   181         a->setEnabled(d->enabled);
       
   182         a->d_func()->forceDisabled = false;
       
   183     }
       
   184     if(!a->d_func()->forceInvisible) {
       
   185         a->setVisible(d->visible);
       
   186         a->d_func()->forceInvisible = false;
       
   187     }
       
   188     if(a->isChecked())
       
   189         d->current = a;
       
   190     QActionGroup *oldGroup = a->d_func()->group;
       
   191     if(oldGroup != this) {
       
   192         if (oldGroup)
       
   193             oldGroup->removeAction(a);
       
   194         a->d_func()->group = this;
       
   195     }
       
   196     return a;
       
   197 }
       
   198 
       
   199 /*!
       
   200     Creates and returns an action with \a text.  The newly created
       
   201     action is a child of this action group.
       
   202 
       
   203     Normally an action is added to a group by creating it with the
       
   204     group as parent, so this function is not usually used.
       
   205 
       
   206     \sa QAction::setActionGroup()
       
   207 */
       
   208 QAction *QActionGroup::addAction(const QString &text)
       
   209 {
       
   210     return new QAction(text, this);
       
   211 }
       
   212 
       
   213 /*!
       
   214     Creates and returns an action with \a text and an \a icon. The
       
   215     newly created action is a child of this action group.
       
   216 
       
   217     Normally an action is added to a group by creating it with the
       
   218     group as its parent, so this function is not usually used.
       
   219 
       
   220     \sa QAction::setActionGroup()
       
   221 */
       
   222 QAction *QActionGroup::addAction(const QIcon &icon, const QString &text)
       
   223 {
       
   224     return new QAction(icon, text, this);
       
   225 }
       
   226 
       
   227 /*!
       
   228   Removes the \a action from this group. The action will have no
       
   229   parent as a result.
       
   230 
       
   231   \sa QAction::setActionGroup()
       
   232 */
       
   233 void QActionGroup::removeAction(QAction *action)
       
   234 {
       
   235     Q_D(QActionGroup);
       
   236     if (d->actions.removeAll(action)) {
       
   237         if (action == d->current)
       
   238             d->current = 0;
       
   239         QObject::disconnect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
       
   240         QObject::disconnect(action, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
       
   241         QObject::disconnect(action, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
       
   242         action->d_func()->group = 0;
       
   243     }
       
   244 }
       
   245 
       
   246 /*!
       
   247     Returns the list of this groups's actions. This may be empty.
       
   248 */
       
   249 QList<QAction*> QActionGroup::actions() const
       
   250 {
       
   251     Q_D(const QActionGroup);
       
   252     return d->actions;
       
   253 }
       
   254 
       
   255 /*!
       
   256     \property QActionGroup::exclusive
       
   257     \brief whether the action group does exclusive checking
       
   258 
       
   259     If exclusive is true, only one checkable action in the action group
       
   260     can ever be active at any time. If the user chooses another
       
   261     checkable action in the group, the one they chose becomes active and
       
   262     the one that was active becomes inactive.
       
   263 
       
   264     \sa QAction::checkable
       
   265 */
       
   266 void QActionGroup::setExclusive(bool b)
       
   267 {
       
   268     Q_D(QActionGroup);
       
   269     d->exclusive = b;
       
   270 }
       
   271 
       
   272 bool QActionGroup::isExclusive() const
       
   273 {
       
   274     Q_D(const QActionGroup);
       
   275     return d->exclusive;
       
   276 }
       
   277 
       
   278 /*!
       
   279     \fn void QActionGroup::setDisabled(bool b)
       
   280 
       
   281     This is a convenience function for the \l enabled property, that
       
   282     is useful for signals--slots connections. If \a b is true the
       
   283     action group is disabled; otherwise it is enabled.
       
   284 */
       
   285 
       
   286 /*!
       
   287     \property QActionGroup::enabled
       
   288     \brief whether the action group is enabled
       
   289 
       
   290     Each action in the group will be enabled or disabled unless it
       
   291     has been explicitly disabled.
       
   292 
       
   293     \sa QAction::setEnabled()
       
   294 */
       
   295 void QActionGroup::setEnabled(bool b)
       
   296 {
       
   297     Q_D(QActionGroup);
       
   298     d->enabled = b;
       
   299     for(QList<QAction*>::const_iterator it = d->actions.constBegin(); it != d->actions.constEnd(); ++it) {
       
   300         if(!(*it)->d_func()->forceDisabled) {
       
   301             (*it)->setEnabled(b);
       
   302             (*it)->d_func()->forceDisabled = false;
       
   303         }
       
   304     }
       
   305 }
       
   306 
       
   307 bool QActionGroup::isEnabled() const
       
   308 {
       
   309     Q_D(const QActionGroup);
       
   310     return d->enabled;
       
   311 }
       
   312 
       
   313 /*!
       
   314   Returns the currently checked action in the group, or 0 if none
       
   315   are checked.
       
   316 */
       
   317 QAction *QActionGroup::checkedAction() const
       
   318 {
       
   319     Q_D(const QActionGroup);
       
   320     return d->current;
       
   321 }
       
   322 
       
   323 /*!
       
   324     \property QActionGroup::visible
       
   325     \brief whether the action group is visible
       
   326 
       
   327     Each action in the action group will match the visible state of
       
   328     this group unless it has been explicitly hidden.
       
   329 
       
   330     \sa QAction::setEnabled()
       
   331 */
       
   332 void QActionGroup::setVisible(bool b)
       
   333 {
       
   334     Q_D(QActionGroup);
       
   335     d->visible = b;
       
   336     for(QList<QAction*>::Iterator it = d->actions.begin(); it != d->actions.end(); ++it) {
       
   337         if(!(*it)->d_func()->forceInvisible) {
       
   338             (*it)->setVisible(b);
       
   339             (*it)->d_func()->forceInvisible = false;
       
   340         }
       
   341     }
       
   342 }
       
   343 
       
   344 bool QActionGroup::isVisible() const
       
   345 {
       
   346     Q_D(const QActionGroup);
       
   347     return d->visible;
       
   348 }
       
   349 
       
   350 /*!
       
   351     \fn void QActionGroup::triggered(QAction *action)
       
   352 
       
   353     This signal is emitted when the given \a action in the action
       
   354     group is activated by the user; for example, when the user clicks
       
   355     a menu option, toolbar button, or presses an action's shortcut key
       
   356     combination.
       
   357 
       
   358     Connect to this signal for command actions.
       
   359 
       
   360     \sa QAction::activate()
       
   361 */
       
   362 
       
   363 /*!
       
   364     \fn void QActionGroup::hovered(QAction *action)
       
   365 
       
   366     This signal is emitted when the given \a action in the action
       
   367     group is highlighted by the user; for example, when the user
       
   368     pauses with the cursor over a menu option, toolbar button, or
       
   369     presses an action's shortcut key combination.
       
   370 
       
   371     \sa QAction::activate()
       
   372 */
       
   373 
       
   374 /*!
       
   375     \fn void QActionGroup::add(QAction* a)
       
   376 
       
   377     Use addAction() instead.
       
   378 */
       
   379 
       
   380 /*!
       
   381     \fn void QActionGroup::addSeparator()
       
   382 
       
   383     Normally you add a separator to the menus or widgets to which
       
   384     actions are added, so this function is very rarely needed.
       
   385 
       
   386     \oldcode
       
   387     actionGroup->addSeparator();
       
   388     \newcode
       
   389     QAction *separator = new QAction(this);
       
   390     separator->setSeparator(true);
       
   391     actionGroup->addAction(separator);
       
   392     \endcode
       
   393 */
       
   394 
       
   395 /*!
       
   396     \fn bool QActionGroup::addTo(QWidget *widget)
       
   397 
       
   398     \oldcode
       
   399     actionGroup->addTo(widget);
       
   400     \newcode
       
   401     widget->addActions(actionGroup->actions());
       
   402     \endcode
       
   403 */
       
   404 
       
   405 /*!
       
   406     \fn void QActionGroup::selected(QAction *action);
       
   407 
       
   408     Use triggered() instead.
       
   409 
       
   410 */
       
   411 
       
   412 QT_END_NAMESPACE
       
   413 
       
   414 #include "moc_qactiongroup.cpp"
       
   415 
       
   416 #endif // QT_NO_ACTION