2015-12-10 05:06:13 +02:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
|
|
|
** Copyright (C) 2015 The Qt Company Ltd.
|
2019-12-29 23:21:34 +00:00
|
|
|
** Copyright (C) 2016-2020 Ivailo Monev
|
2015-12-10 05:06:13 +02:00
|
|
|
**
|
2019-06-03 13:38:02 +00:00
|
|
|
** This file is part of the QtGui module of the Katie Toolkit.
|
2015-12-10 05:06:13 +02:00
|
|
|
**
|
|
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
|
|
**
|
|
|
|
** GNU Lesser General Public License Usage
|
2019-12-29 23:21:34 +00:00
|
|
|
** This file may be used under the terms of the GNU Lesser
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2015-12-10 05:06:13 +02:00
|
|
|
**
|
|
|
|
** As a special exception, The Qt Company gives you certain additional
|
|
|
|
** rights. These rights are described in The Qt Company LGPL Exception
|
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
**
|
|
|
|
** GNU General Public License Usage
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
** General Public License version 3.0 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU General Public License version 3.0 requirements will be
|
|
|
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
|
|
|
**
|
|
|
|
** $QT_END_LICENSE$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "qactiongroup.h"
|
|
|
|
|
|
|
|
#ifndef QT_NO_ACTION
|
|
|
|
|
|
|
|
#include "qaction_p.h"
|
|
|
|
#include "qapplication.h"
|
|
|
|
#include "qevent.h"
|
|
|
|
#include "qlist.h"
|
|
|
|
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
|
|
|
class QActionGroupPrivate : public QObjectPrivate
|
|
|
|
{
|
|
|
|
Q_DECLARE_PUBLIC(QActionGroup)
|
|
|
|
public:
|
2019-07-13 20:30:51 +00:00
|
|
|
QActionGroupPrivate() : exclusive(true), enabled(true), visible(true) { }
|
2015-12-10 05:06:13 +02:00
|
|
|
QList<QAction *> actions;
|
|
|
|
QPointer<QAction> current;
|
2019-07-13 20:30:51 +00:00
|
|
|
bool exclusive;
|
|
|
|
bool enabled;
|
|
|
|
bool visible;
|
2015-12-10 05:06:13 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
void _q_actionTriggered(); //private slot
|
|
|
|
void _q_actionChanged(); //private slot
|
|
|
|
void _q_actionHovered(); //private slot
|
|
|
|
};
|
|
|
|
|
|
|
|
void QActionGroupPrivate::_q_actionChanged()
|
|
|
|
{
|
|
|
|
Q_Q(QActionGroup);
|
|
|
|
QAction *action = qobject_cast<QAction*>(q->sender());
|
|
|
|
Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error");
|
|
|
|
if(exclusive) {
|
|
|
|
if (action->isChecked()) {
|
|
|
|
if (action != current) {
|
|
|
|
if(current)
|
|
|
|
current->setChecked(false);
|
|
|
|
current = action;
|
|
|
|
}
|
|
|
|
} else if (action == current) {
|
|
|
|
current = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QActionGroupPrivate::_q_actionTriggered()
|
|
|
|
{
|
|
|
|
Q_Q(QActionGroup);
|
|
|
|
QAction *action = qobject_cast<QAction*>(q->sender());
|
|
|
|
Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionTriggered", "internal error");
|
|
|
|
emit q->triggered(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QActionGroupPrivate::_q_actionHovered()
|
|
|
|
{
|
|
|
|
Q_Q(QActionGroup);
|
|
|
|
QAction *action = qobject_cast<QAction*>(q->sender());
|
|
|
|
Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionHovered", "internal error");
|
|
|
|
emit q->hovered(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class QActionGroup
|
|
|
|
\brief The QActionGroup class groups actions together.
|
|
|
|
|
|
|
|
\ingroup mainwindow-classes
|
|
|
|
|
|
|
|
In some situations it is useful to group QAction objects together.
|
|
|
|
For example, if you have a \gui{Left Align} action, a \gui{Right
|
|
|
|
Align} action, a \gui{Justify} action, and a \gui{Center} action,
|
|
|
|
only one of these actions should be active at any one time. One
|
|
|
|
simple way of achieving this is to group the actions together in
|
|
|
|
an action group.
|
|
|
|
|
|
|
|
Here's a example (from the \l{mainwindows/menus}{Menus} example):
|
|
|
|
|
|
|
|
\snippet examples/mainwindows/menus/mainwindow.cpp 6
|
|
|
|
|
|
|
|
Here we create a new action group. Since the action group is
|
|
|
|
exclusive by default, only one of the actions in the group is
|
|
|
|
checked at any one time.
|
|
|
|
|
|
|
|
\img qactiongroup-align.png Alignment options in a QMenu
|
|
|
|
|
|
|
|
A QActionGroup emits an triggered() signal when one of its
|
|
|
|
actions is chosen. Each action in an action group emits its
|
|
|
|
triggered() signal as usual.
|
|
|
|
|
|
|
|
As stated above, an action group is \l exclusive by default; it
|
|
|
|
ensures that only one checkable action is active at any one time.
|
|
|
|
If you want to group checkable actions without making them
|
|
|
|
exclusive, you can turn of exclusiveness by calling
|
|
|
|
setExclusive(false).
|
|
|
|
|
|
|
|
Actions can be added to an action group using addAction(), but it
|
|
|
|
is usually more convenient to specify a group when creating
|
|
|
|
actions; this ensures that actions are automatically created with
|
|
|
|
a parent. Actions can be visually separated from each other by
|
|
|
|
adding a separator action to the group; create an action and use
|
|
|
|
QAction's \l {QAction::}{setSeparator()} function to make it
|
|
|
|
considered a separator. Action groups are added to widgets with
|
|
|
|
the QWidget::addActions() function.
|
|
|
|
|
|
|
|
\sa QAction
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs an action group for the \a parent object.
|
|
|
|
|
|
|
|
The action group is exclusive by default. Call setExclusive(false)
|
|
|
|
to make the action group non-exclusive.
|
|
|
|
*/
|
|
|
|
QActionGroup::QActionGroup(QObject* parent) : QObject(*new QActionGroupPrivate, parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Destroys the action group.
|
|
|
|
*/
|
|
|
|
QActionGroup::~QActionGroup()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QAction *QActionGroup::addAction(QAction *action)
|
|
|
|
|
|
|
|
Adds the \a action to this group, and returns it.
|
|
|
|
|
|
|
|
Normally an action is added to a group by creating it with the
|
|
|
|
group as its parent, so this function is not usually used.
|
|
|
|
|
|
|
|
\sa QAction::setActionGroup()
|
|
|
|
*/
|
|
|
|
QAction *QActionGroup::addAction(QAction* a)
|
|
|
|
{
|
|
|
|
Q_D(QActionGroup);
|
|
|
|
if(!d->actions.contains(a)) {
|
|
|
|
d->actions.append(a);
|
|
|
|
QObject::connect(a, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
|
|
|
|
QObject::connect(a, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
|
|
|
|
QObject::connect(a, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
|
|
|
|
}
|
2016-08-07 13:46:51 +00:00
|
|
|
a->setEnabled(d->enabled);
|
|
|
|
a->setVisible(d->visible);
|
2015-12-10 05:06:13 +02:00
|
|
|
if(a->isChecked())
|
|
|
|
d->current = a;
|
|
|
|
QActionGroup *oldGroup = a->d_func()->group;
|
|
|
|
if(oldGroup != this) {
|
|
|
|
if (oldGroup)
|
|
|
|
oldGroup->removeAction(a);
|
|
|
|
a->d_func()->group = this;
|
|
|
|
}
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Creates and returns an action with \a text. The newly created
|
|
|
|
action is a child of this action group.
|
|
|
|
|
|
|
|
Normally an action is added to a group by creating it with the
|
|
|
|
group as parent, so this function is not usually used.
|
|
|
|
|
|
|
|
\sa QAction::setActionGroup()
|
|
|
|
*/
|
|
|
|
QAction *QActionGroup::addAction(const QString &text)
|
|
|
|
{
|
|
|
|
return new QAction(text, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Creates and returns an action with \a text and an \a icon. The
|
|
|
|
newly created action is a child of this action group.
|
|
|
|
|
|
|
|
Normally an action is added to a group by creating it with the
|
|
|
|
group as its parent, so this function is not usually used.
|
|
|
|
|
|
|
|
\sa QAction::setActionGroup()
|
|
|
|
*/
|
|
|
|
QAction *QActionGroup::addAction(const QIcon &icon, const QString &text)
|
|
|
|
{
|
|
|
|
return new QAction(icon, text, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Removes the \a action from this group. The action will have no
|
|
|
|
parent as a result.
|
|
|
|
|
|
|
|
\sa QAction::setActionGroup()
|
|
|
|
*/
|
|
|
|
void QActionGroup::removeAction(QAction *action)
|
|
|
|
{
|
|
|
|
Q_D(QActionGroup);
|
|
|
|
if (d->actions.removeAll(action)) {
|
|
|
|
if (action == d->current)
|
|
|
|
d->current = 0;
|
|
|
|
QObject::disconnect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
|
|
|
|
QObject::disconnect(action, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
|
|
|
|
QObject::disconnect(action, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
|
|
|
|
action->d_func()->group = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the list of this groups's actions. This may be empty.
|
|
|
|
*/
|
|
|
|
QList<QAction*> QActionGroup::actions() const
|
|
|
|
{
|
|
|
|
Q_D(const QActionGroup);
|
|
|
|
return d->actions;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\property QActionGroup::exclusive
|
|
|
|
\brief whether the action group does exclusive checking
|
|
|
|
|
|
|
|
If exclusive is true, only one checkable action in the action group
|
|
|
|
can ever be active at any time. If the user chooses another
|
|
|
|
checkable action in the group, the one they chose becomes active and
|
|
|
|
the one that was active becomes inactive.
|
|
|
|
|
|
|
|
\sa QAction::checkable
|
|
|
|
*/
|
|
|
|
void QActionGroup::setExclusive(bool b)
|
|
|
|
{
|
|
|
|
Q_D(QActionGroup);
|
|
|
|
d->exclusive = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QActionGroup::isExclusive() const
|
|
|
|
{
|
|
|
|
Q_D(const QActionGroup);
|
|
|
|
return d->exclusive;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QActionGroup::setDisabled(bool b)
|
|
|
|
|
|
|
|
This is a convenience function for the \l enabled property, that
|
|
|
|
is useful for signals--slots connections. If \a b is true the
|
|
|
|
action group is disabled; otherwise it is enabled.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\property QActionGroup::enabled
|
|
|
|
\brief whether the action group is enabled
|
|
|
|
|
2020-01-26 22:52:37 +00:00
|
|
|
Each action in the group will be enabled or disabled.
|
2015-12-10 05:06:13 +02:00
|
|
|
|
|
|
|
\sa QAction::setEnabled()
|
|
|
|
*/
|
|
|
|
void QActionGroup::setEnabled(bool b)
|
|
|
|
{
|
|
|
|
Q_D(QActionGroup);
|
|
|
|
d->enabled = b;
|
2019-07-13 20:30:51 +00:00
|
|
|
foreach(QAction* it, d->actions) {
|
|
|
|
it->setEnabled(b);
|
2015-12-10 05:06:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QActionGroup::isEnabled() const
|
|
|
|
{
|
|
|
|
Q_D(const QActionGroup);
|
|
|
|
return d->enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the currently checked action in the group, or 0 if none
|
|
|
|
are checked.
|
|
|
|
*/
|
|
|
|
QAction *QActionGroup::checkedAction() const
|
|
|
|
{
|
|
|
|
Q_D(const QActionGroup);
|
|
|
|
return d->current;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\property QActionGroup::visible
|
|
|
|
\brief whether the action group is visible
|
|
|
|
|
|
|
|
Each action in the action group will match the visible state of
|
2020-01-26 22:52:37 +00:00
|
|
|
this group.
|
2015-12-10 05:06:13 +02:00
|
|
|
|
|
|
|
\sa QAction::setEnabled()
|
|
|
|
*/
|
|
|
|
void QActionGroup::setVisible(bool b)
|
|
|
|
{
|
|
|
|
Q_D(QActionGroup);
|
|
|
|
d->visible = b;
|
2019-07-13 20:30:51 +00:00
|
|
|
foreach(QAction* it, d->actions) {
|
|
|
|
it->setVisible(b);
|
2015-12-10 05:06:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QActionGroup::isVisible() const
|
|
|
|
{
|
|
|
|
Q_D(const QActionGroup);
|
|
|
|
return d->visible;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QActionGroup::triggered(QAction *action)
|
|
|
|
|
|
|
|
This signal is emitted when the given \a action in the action
|
|
|
|
group is activated by the user; for example, when the user clicks
|
|
|
|
a menu option, toolbar button, or presses an action's shortcut key
|
|
|
|
combination.
|
|
|
|
|
|
|
|
Connect to this signal for command actions.
|
|
|
|
|
|
|
|
\sa QAction::activate()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QActionGroup::hovered(QAction *action)
|
|
|
|
|
|
|
|
This signal is emitted when the given \a action in the action
|
|
|
|
group is highlighted by the user; for example, when the user
|
|
|
|
pauses with the cursor over a menu option, toolbar button, or
|
|
|
|
presses an action's shortcut key combination.
|
|
|
|
|
|
|
|
\sa QAction::activate()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QActionGroup::add(QAction* a)
|
|
|
|
|
|
|
|
Use addAction() instead.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QActionGroup::addSeparator()
|
|
|
|
|
|
|
|
Normally you add a separator to the menus or widgets to which
|
|
|
|
actions are added, so this function is very rarely needed.
|
|
|
|
|
|
|
|
\oldcode
|
|
|
|
actionGroup->addSeparator();
|
|
|
|
\newcode
|
|
|
|
QAction *separator = new QAction(this);
|
|
|
|
separator->setSeparator(true);
|
|
|
|
actionGroup->addAction(separator);
|
|
|
|
\endcode
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QActionGroup::addTo(QWidget *widget)
|
|
|
|
|
|
|
|
\oldcode
|
|
|
|
actionGroup->addTo(widget);
|
|
|
|
\newcode
|
|
|
|
widget->addActions(actionGroup->actions());
|
|
|
|
\endcode
|
|
|
|
*/
|
|
|
|
|
|
|
|
QT_END_NAMESPACE
|
|
|
|
|
|
|
|
|
|
|
|
#include "moc_qactiongroup.h"
|
|
|
|
|
|
|
|
#endif // QT_NO_ACTION
|