util/src/gui/kernel/qactiongroup.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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) {
       
    76         if (action->isChecked()) {
       
    77             if (action != current) {
       
    78                 if(current)
       
    79                     current->setChecked(false);
       
    80                 current = action;
       
    81             }
       
    82         } else if (action == current) {
       
    83             current = 0;
       
    84         }
       
    85     }
       
    86 }
       
    87 
       
    88 void QActionGroupPrivate::_q_actionTriggered()
       
    89 {
       
    90     Q_Q(QActionGroup);
       
    91     QAction *action = qobject_cast<QAction*>(q->sender());
       
    92     Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionTriggered", "internal error");
       
    93     emit q->triggered(action);
       
    94     emit q->selected(action);
       
    95 }
       
    96 
       
    97 void QActionGroupPrivate::_q_actionHovered()
       
    98 {
       
    99     Q_Q(QActionGroup);
       
   100     QAction *action = qobject_cast<QAction*>(q->sender());
       
   101     Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionHovered", "internal error");
       
   102     emit q->hovered(action);
       
   103 }
       
   104 
       
   105 /*!
       
   106     \class QActionGroup
       
   107     \brief The QActionGroup class groups actions together.
       
   108 
       
   109     \ingroup mainwindow-classes
       
   110 
       
   111     In some situations it is useful to group actions together. For
       
   112     example, if you have a \gui{Left Align} action, a \gui{Right
       
   113     Align} action, a \gui{Justify} action, and a \gui{Center} action,
       
   114     only one of these actions should be active at any one time. One
       
   115     simple way of achieving this is to group the actions together in
       
   116     an action group.
       
   117 
       
   118     Here's a example (from the \l{mainwindows/menus}{Menus} example):
       
   119 
       
   120     \snippet examples/mainwindows/menus/mainwindow.cpp 6
       
   121 
       
   122     Here we create a new action group. Since the action group is
       
   123     exclusive by default, only one of the actions in the group is
       
   124     checked at any one time.
       
   125 
       
   126     \img qactiongroup-align.png Alignment options in a QMenu
       
   127 
       
   128     A QActionGroup emits an triggered() signal when one of its
       
   129     actions is chosen. Each action in an action group emits its
       
   130     triggered() signal as usual.
       
   131 
       
   132     As stated above, an action group is \l exclusive by default; it
       
   133     ensures that only one checkable action is active at any one time.
       
   134     If you want to group checkable actions without making them
       
   135     exclusive, you can turn of exclusiveness by calling
       
   136     setExclusive(false).
       
   137 
       
   138     Actions can be added to an action group using addAction(), but it
       
   139     is usually more convenient to specify a group when creating
       
   140     actions; this ensures that actions are automatically created with
       
   141     a parent. Actions can be visually separated from each other by
       
   142     adding a separator action to the group; create an action and use
       
   143     QAction's \l {QAction::}{setSeparator()} function to make it
       
   144     considered a separator. Action groups are added to widgets with
       
   145     the QWidget::addActions() function.
       
   146 
       
   147     \sa QAction
       
   148 */
       
   149 
       
   150 /*!
       
   151     Constructs an action group for the \a parent object.
       
   152 
       
   153     The action group is exclusive by default. Call setExclusive(false)
       
   154     to make the action group non-exclusive.
       
   155 */
       
   156 QActionGroup::QActionGroup(QObject* parent) : QObject(*new QActionGroupPrivate, parent)
       
   157 {
       
   158 }
       
   159 
       
   160 /*!
       
   161     Destroys the action group.
       
   162 */
       
   163 QActionGroup::~QActionGroup()
       
   164 {
       
   165 }
       
   166 
       
   167 /*!
       
   168     \fn QAction *QActionGroup::addAction(QAction *action)
       
   169 
       
   170     Adds the \a action to this group, and returns it.
       
   171 
       
   172     Normally an action is added to a group by creating it with the
       
   173     group as its parent, so this function is not usually used.
       
   174 
       
   175     \sa QAction::setActionGroup()
       
   176 */
       
   177 QAction *QActionGroup::addAction(QAction* a)
       
   178 {
       
   179     Q_D(QActionGroup);
       
   180     if(!d->actions.contains(a)) {
       
   181         d->actions.append(a);
       
   182         QObject::connect(a, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
       
   183         QObject::connect(a, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
       
   184         QObject::connect(a, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
       
   185     }
       
   186     if(!a->d_func()->forceDisabled) {
       
   187         a->setEnabled(d->enabled);
       
   188         a->d_func()->forceDisabled = false;
       
   189     }
       
   190     if(!a->d_func()->forceInvisible) {
       
   191         a->setVisible(d->visible);
       
   192         a->d_func()->forceInvisible = false;
       
   193     }
       
   194     if(a->isChecked())
       
   195         d->current = a;
       
   196     QActionGroup *oldGroup = a->d_func()->group;
       
   197     if(oldGroup != this) {
       
   198         if (oldGroup)
       
   199             oldGroup->removeAction(a);
       
   200         a->d_func()->group = this;
       
   201     }
       
   202     return a;
       
   203 }
       
   204 
       
   205 /*!
       
   206     Creates and returns an action with \a text.  The newly created
       
   207     action is a child of this action group.
       
   208 
       
   209     Normally an action is added to a group by creating it with the
       
   210     group as parent, so this function is not usually used.
       
   211 
       
   212     \sa QAction::setActionGroup()
       
   213 */
       
   214 QAction *QActionGroup::addAction(const QString &text)
       
   215 {
       
   216     return new QAction(text, this);
       
   217 }
       
   218 
       
   219 /*!
       
   220     Creates and returns an action with \a text and an \a icon. The
       
   221     newly created action is a child of this action group.
       
   222 
       
   223     Normally an action is added to a group by creating it with the
       
   224     group as its parent, so this function is not usually used.
       
   225 
       
   226     \sa QAction::setActionGroup()
       
   227 */
       
   228 QAction *QActionGroup::addAction(const QIcon &icon, const QString &text)
       
   229 {
       
   230     return new QAction(icon, text, this);
       
   231 }
       
   232 
       
   233 /*!
       
   234   Removes the \a action from this group. The action will have no
       
   235   parent as a result.
       
   236 
       
   237   \sa QAction::setActionGroup()
       
   238 */
       
   239 void QActionGroup::removeAction(QAction *action)
       
   240 {
       
   241     Q_D(QActionGroup);
       
   242     if (d->actions.removeAll(action)) {
       
   243         if (action == d->current)
       
   244             d->current = 0;
       
   245         QObject::disconnect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
       
   246         QObject::disconnect(action, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
       
   247         QObject::disconnect(action, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
       
   248         action->d_func()->group = 0;
       
   249     }
       
   250 }
       
   251 
       
   252 /*!
       
   253     Returns the list of this groups's actions. This may be empty.
       
   254 */
       
   255 QList<QAction*> QActionGroup::actions() const
       
   256 {
       
   257     Q_D(const QActionGroup);
       
   258     return d->actions;
       
   259 }
       
   260 
       
   261 /*!
       
   262     \property QActionGroup::exclusive
       
   263     \brief whether the action group does exclusive checking
       
   264 
       
   265     If exclusive is true, only one checkable action in the action group
       
   266     can ever be active at any time. If the user chooses another
       
   267     checkable action in the group, the one they chose becomes active and
       
   268     the one that was active becomes inactive.
       
   269 
       
   270     \sa QAction::checkable
       
   271 */
       
   272 void QActionGroup::setExclusive(bool b)
       
   273 {
       
   274     Q_D(QActionGroup);
       
   275     d->exclusive = b;
       
   276 }
       
   277 
       
   278 bool QActionGroup::isExclusive() const
       
   279 {
       
   280     Q_D(const QActionGroup);
       
   281     return d->exclusive;
       
   282 }
       
   283 
       
   284 /*!
       
   285     \fn void QActionGroup::setDisabled(bool b)
       
   286 
       
   287     This is a convenience function for the \l enabled property, that
       
   288     is useful for signals--slots connections. If \a b is true the
       
   289     action group is disabled; otherwise it is enabled.
       
   290 */
       
   291 
       
   292 /*!
       
   293     \property QActionGroup::enabled
       
   294     \brief whether the action group is enabled
       
   295 
       
   296     Each action in the group will be enabled or disabled unless it
       
   297     has been explicitly disabled.
       
   298 
       
   299     \sa QAction::setEnabled()
       
   300 */
       
   301 void QActionGroup::setEnabled(bool b)
       
   302 {
       
   303     Q_D(QActionGroup);
       
   304     d->enabled = b;
       
   305     for(QList<QAction*>::const_iterator it = d->actions.constBegin(); it != d->actions.constEnd(); ++it) {
       
   306         if(!(*it)->d_func()->forceDisabled) {
       
   307             (*it)->setEnabled(b);
       
   308             (*it)->d_func()->forceDisabled = false;
       
   309         }
       
   310     }
       
   311 }
       
   312 
       
   313 bool QActionGroup::isEnabled() const
       
   314 {
       
   315     Q_D(const QActionGroup);
       
   316     return d->enabled;
       
   317 }
       
   318 
       
   319 /*!
       
   320   Returns the currently checked action in the group, or 0 if none
       
   321   are checked.
       
   322 */
       
   323 QAction *QActionGroup::checkedAction() const
       
   324 {
       
   325     Q_D(const QActionGroup);
       
   326     return d->current;
       
   327 }
       
   328 
       
   329 /*!
       
   330     \property QActionGroup::visible
       
   331     \brief whether the action group is visible
       
   332 
       
   333     Each action in the action group will match the visible state of
       
   334     this group unless it has been explicitly hidden.
       
   335 
       
   336     \sa QAction::setEnabled()
       
   337 */
       
   338 void QActionGroup::setVisible(bool b)
       
   339 {
       
   340     Q_D(QActionGroup);
       
   341     d->visible = b;
       
   342     for(QList<QAction*>::Iterator it = d->actions.begin(); it != d->actions.end(); ++it) {
       
   343         if(!(*it)->d_func()->forceInvisible) {
       
   344             (*it)->setVisible(b);
       
   345             (*it)->d_func()->forceInvisible = false;
       
   346         }
       
   347     }
       
   348 }
       
   349 
       
   350 bool QActionGroup::isVisible() const
       
   351 {
       
   352     Q_D(const QActionGroup);
       
   353     return d->visible;
       
   354 }
       
   355 
       
   356 /*!
       
   357     \fn void QActionGroup::triggered(QAction *action)
       
   358 
       
   359     This signal is emitted when the given \a action in the action
       
   360     group is activated by the user; for example, when the user clicks
       
   361     a menu option, toolbar button, or presses an action's shortcut key
       
   362     combination.
       
   363 
       
   364     Connect to this signal for command actions.
       
   365 
       
   366     \sa QAction::activate()
       
   367 */
       
   368 
       
   369 /*!
       
   370     \fn void QActionGroup::hovered(QAction *action)
       
   371 
       
   372     This signal is emitted when the given \a action in the action
       
   373     group is highlighted by the user; for example, when the user
       
   374     pauses with the cursor over a menu option, toolbar button, or
       
   375     presses an action's shortcut key combination.
       
   376 
       
   377     \sa QAction::activate()
       
   378 */
       
   379 
       
   380 /*!
       
   381     \fn void QActionGroup::add(QAction* a)
       
   382 
       
   383     Use addAction() instead.
       
   384 */
       
   385 
       
   386 /*!
       
   387     \fn void QActionGroup::addSeparator()
       
   388 
       
   389     Normally you add a separator to the menus or widgets to which
       
   390     actions are added, so this function is very rarely needed.
       
   391 
       
   392     \oldcode
       
   393     actionGroup->addSeparator();
       
   394     \newcode
       
   395     QAction *separator = new QAction(this);
       
   396     separator->setSeparator(true);
       
   397     actionGroup->addAction(separator);
       
   398     \endcode
       
   399 */
       
   400 
       
   401 /*!
       
   402     \fn bool QActionGroup::addTo(QWidget *widget)
       
   403 
       
   404     \oldcode
       
   405     actionGroup->addTo(widget);
       
   406     \newcode
       
   407     widget->addActions(actionGroup->actions());
       
   408     \endcode
       
   409 */
       
   410 
       
   411 /*!
       
   412     \fn void QActionGroup::selected(QAction *action);
       
   413 
       
   414     Use triggered() instead.
       
   415 
       
   416 */
       
   417 
       
   418 QT_END_NAMESPACE
       
   419 
       
   420 #include "moc_qactiongroup.cpp"
       
   421 
       
   422 #endif // QT_NO_ACTION