/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qactiongroup.h"

#ifndef QT_NO_ACTION

#include "qaction_p.h"
#include "qevent.h"
#include "qlist.h"

QT_BEGIN_NAMESPACE

class QActionGroupPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QActionGroup)
public:
    QActionGroupPrivate() : enabled(1),
                            visible(1),
                            exclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive)
    {
    }
    QList<QAction *> actions;
    QPointer<QAction> current;
    uint enabled : 1;
    uint visible : 1;
    QActionGroup::ExclusionPolicy exclusionPolicy;

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 != nullptr, "QActionGroup::_q_actionChanged", "internal error");
    if (exclusionPolicy != QActionGroup::ExclusionPolicy::None) {
        if (action->isChecked()) {
            if (action != current) {
                if(current)
                    current->setChecked(false);
                current = action;
            }
        } else if (action == current) {
            current = nullptr;
        }
    }
}

void QActionGroupPrivate::_q_actionTriggered()
{
    Q_Q(QActionGroup);
    QAction *action = qobject_cast<QAction*>(q->sender());
    Q_ASSERT_X(action != nullptr, "QActionGroup::_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 != nullptr, "QActionGroup::_q_actionHovered", "internal error");
    emit q->hovered(action);
}

/*!
    \class QActionGroup
    \brief The QActionGroup class groups actions together.

    \ingroup mainwindow-classes
    \inmodule QtWidgets

    In some situations it is useful to group QAction objects together.
    For example, if you have a \uicontrol{Left Align} action, a \uicontrol{Right
    Align} action, a \uicontrol{Justify} action, and a \uicontrol{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 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.

    \image 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 exclusive by default; it
    ensures that at most only one checkable action is active at any one time.
    If you want to group checkable actions without making them
    exclusive, you can turn off exclusiveness by calling
    setExclusive(false).

    By default the active action of an exclusive group cannot be unchecked.
    In some cases it may be useful to allow unchecking all the actions,
    you can allow this by calling
    setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional).

    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
*/

/*!
    \enum QActionGroup::ExclusionPolicy

    This enum specifies the different policies that can be used to
    control how the group performs exclusive checking on checkable actions.

    \value None
           The actions in the group can be checked independently of each other.

    \value Exclusive
           Exactly one action can be checked at any one time.
           This is the default policy.

    \value ExclusiveOptional
           At most one action can be checked at any one time. The actions
           can also be all unchecked.

    \sa exclusionPolicy
    \since 5.14
*/

/*!
    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. To make the group exclusive
    but allow unchecking the active action call instead
    setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional)
*/
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()));
    }
    if(!a->d_func()->forceDisabled) {
        a->setEnabled(d->enabled);
        a->d_func()->forceDisabled = false;
    }
    if(!a->d_func()->forceInvisible) {
        a->setVisible(d->visible);
        a->d_func()->forceInvisible = false;
    }
    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;
        a->d_func()->sendDataChanged();
    }
    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 = nullptr;
        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 = nullptr;
    }
}

/*!
    Returns the list of this groups's actions. This may be empty.
*/
QList<QAction*> QActionGroup::actions() const
{
    Q_D(const QActionGroup);
    return d->actions;
}

/*!
    \brief Enable or disable the group exclusion checking

    This is a convenience method that calls
    setExclusionPolicy(ExclusionPolicy::Exclusive) when \a b is true,
    else setExclusionPolicy(QActionGroup::ExclusionPolicy::None).

    \sa QActionGroup::exclusionPolicy
*/
void QActionGroup::setExclusive(bool b)
{
    setExclusionPolicy(b ? QActionGroup::ExclusionPolicy::Exclusive
                         : QActionGroup::ExclusionPolicy::None);
}

/*!
    \brief Returns true if the group is exclusive

    The group is exclusive if the ExclusionPolicy is either Exclusive
    or ExclusionOptional.

*/
bool QActionGroup::isExclusive() const
{
    return exclusionPolicy() != QActionGroup::ExclusionPolicy::None;
}

/*!
    \property QActionGroup::exclusionPolicy
    \brief This property holds the group exclusive checking policy

    If exclusionPolicy is set to Exclusive, 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. If exclusionPolicy is
    set to ExclusionOptional the group is exclusive but the active checkable
    action in the group can be unchecked leaving the group with no actions
    checked.

    \sa QAction::checkable
    \since 5.14
*/
void QActionGroup::setExclusionPolicy(QActionGroup::ExclusionPolicy policy)
{
    Q_D(QActionGroup);
    d->exclusionPolicy = policy;
}

QActionGroup::ExclusionPolicy QActionGroup::exclusionPolicy() const
{
    Q_D(const QActionGroup);
    return d->exclusionPolicy;
}

/*!
    \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

    Each action in the group will be enabled or disabled unless it
    has been explicitly disabled.

    \sa QAction::setEnabled()
*/
void QActionGroup::setEnabled(bool b)
{
    Q_D(QActionGroup);
    d->enabled = b;
    for (auto action : qAsConst(d->actions)) {
        if (!action->d_func()->forceDisabled) {
            action->setEnabled(b);
            action->d_func()->forceDisabled = false;
        }
    }
}

bool QActionGroup::isEnabled() const
{
    Q_D(const QActionGroup);
    return d->enabled;
}

/*!
  Returns the currently checked action in the group, or \nullptr 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
    this group unless it has been explicitly hidden.

    \sa QAction::setEnabled()
*/
void QActionGroup::setVisible(bool b)
{
    Q_D(QActionGroup);
    d->visible = b;
    for (auto action : qAsConst(d->actions)) {
        if (!action->d_func()->forceInvisible) {
            action->setVisible(b);
            action->d_func()->forceInvisible = false;
        }
    }
}

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()
*/

QT_END_NAMESPACE

#include "moc_qactiongroup.cpp"

#endif // QT_NO_ACTION
