/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 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 "qquickaction_p.h"
#include "qquickexclusivegroup_p.h"
#include "qquickmenuitem_p.h"

#include <QtGui/qguiapplication.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickwindow.h>
#include <private/qguiapplication_p.h>
#include <qqmlfile.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype Action
    \instantiates QQuickAction1
    \ingroup applicationwindow
    \ingroup controls
    \inqmlmodule QtQuick.Controls
    \brief Action provides an abstract user interface action that can be bound to items.

    \image menubar-action.png

    In applications many common commands can be invoked via menus, toolbar buttons, and keyboard
    shortcuts. Since the user expects each command to be performed in the same way, regardless of
    the user interface used, it is useful to represent each command as an \e action.

    An action can be bound to a menu item and a toolbar button, and it will automatically keep them in sync.
    For example, in a word processor, if the user presses a Bold toolbar button, the Bold menu item will
    automatically be checked.

    QtQuick Controls supports actions in \l {QtQuick.Controls::}{Button}, \l ToolButton, and \l MenuItem.

    \quotefromfile gallery/main.qml
    \dots
    \skipto Action
    \printto TabView
    \dots
*/

/*!
    \qmlproperty string Action::text

    Text for the action. This text will show as the button text, or
    as title in a menu item.

    Mnemonics are supported by prefixing the shortcut letter with \&.
    For instance, \c "\&Open" will bind the \c Alt-O shortcut to the
    \c "Open" menu item. Note that not all platforms support mnemonics.

    Defaults to an empty string.
*/

/*!
    \qmlproperty url Action::iconSource

    Sets the icon file or resource url for the action. Defaults to an empty URL.
*/

/*!
    \qmlproperty string Action::iconName

    Sets the icon name for the action. This will pick the icon
    with the given name from the current theme.

    Defaults to an empty string.

    \include icons.qdocinc iconName
*/

/*!
    \qmlproperty string Action::tooltip

    Tooltip to be shown when hovering the control bound to this action.
    Not all controls support tooltips on all platforms, especially \l MenuItem.

    Defaults to an empty string.
*/

/*!
    \qmlproperty bool Action::enabled

    Whether the action is enabled, and can be triggered. Defaults to \c true.

    \sa trigger(), triggered
*/

/*!
    \qmlproperty bool Action::checkable

     Whether the menu item can be checked, or toggled. Defaults to \c false.

     \sa checked, exclusiveGroup
*/

/*!
    \qmlproperty bool Action::checked

    If the action is \l checkable, this property reflects its checked state. Defaults to \c false.
    Its value is also false while \l checkable is false.

    \sa toggled, exclusiveGroup
*/

/*!
    \qmlproperty ExclusiveGroup Action::exclusiveGroup

    If an action is checkable, an \l ExclusiveGroup can be attached to it.
    All the actions sharing the same exclusive group become mutually exclusive
    selectable, meaning that only the last checked action will actually be checked.

    Defaults to \c null, meaning no exclusive behavior is to be expected.

    \sa checkable, checked
*/

/*!
    \qmlproperty keysequence Action::shortcut

    Shortcut bound to the action. The keysequence can be a string
    or a \l {QKeySequence::StandardKey}{standard key}.

    Defaults to an empty string.

    \qml
    Action {
        id: copyAction
        text: qsTr("&Copy")
        shortcut: StandardKey.Copy
    }
    \endqml
*/

/*! \qmlsignal Action::triggered(QtObject source)

    Emitted when either the menu item or its bound action have been activated. Includes
    the object (\a source) that triggered the event if relevant (e.g. a Button or MenuItem).
    You shouldn't need to emit this signal, use \l trigger() instead.

    The corresponding handler is \c onTriggered.
*/

/*! \qmlmethod void Action::trigger(QtObject source)

    Will emit the \l triggered signal on \a source if the action is enabled. You may provide
    a source object if the Action would benefit from knowing the origin of the triggering
    (e.g. for analytics). Will also emit the \l toggled signal if it is checkable.
*/

/*! \qmlsignal Action::toggled(checked)

    Emitted whenever an action's \a checked property changes.
    This usually happens at the same time as \l triggered.

    The corresponding handler is \c onToggled.

    \sa checked
*/

QQuickAction1::QQuickAction1(QObject *parent)
    : QObject(parent)
    , m_enabled(true)
    , m_checkable(false)
    , m_checked(false)
{
}

QQuickAction1::~QQuickAction1()
{
    setShortcut(QString());
    setMnemonicFromText(QString());
    setExclusiveGroup(0);
}

void QQuickAction1::setText(const QString &text)
{
    if (text == m_text)
        return;
    m_text = text;
    setMnemonicFromText(m_text);
    emit textChanged();
}

namespace {

bool qShortcutContextMatcher(QObject *o, Qt::ShortcutContext context)
{
    if (!static_cast<QQuickAction1*>(o)->isEnabled())
        return false;

    switch (context) {
    case Qt::ApplicationShortcut:
        return true;
    case Qt::WindowShortcut: {
        QObject *w = o;
        while (w && !w->isWindowType()) {
            w = w->parent();
            if (QQuickItem * item = qobject_cast<QQuickItem*>(w))
                w = item->window();
        }
        if (w && w == QGuiApplication::focusWindow())
            return true;
    }
    case Qt::WidgetShortcut:
    case Qt::WidgetWithChildrenShortcut:
        break;
    }

    return false;
}

bool qMnemonicContextMatcher(QObject *o, Qt::ShortcutContext context)
{
    if (!static_cast<QQuickAction1*>(o)->isEnabled())
        return false;

    switch (context) {
    case Qt::ApplicationShortcut:
        return true;
    case Qt::WindowShortcut: {
        QObject *w = o;
        while (w && !w->isWindowType()) {
            w = w->parent();
            if (QQuickItem * item = qobject_cast<QQuickItem*>(w))
                w = item->window();
            else if (QQuickMenuBase1 *mb = qobject_cast<QQuickMenuBase1 *>(w)) {
                QQuickItem *vi = mb->visualItem();
                if (vi && vi->isVisible())
                    w = vi->window();
                else
                    break; // Non visible menu objects don't get mnemonic match
            }
        }
        if (w && w == QGuiApplication::focusWindow())
            return true;
    }
    case Qt::WidgetShortcut:
    case Qt::WidgetWithChildrenShortcut:
        break;
    }

    return false;
}

} // namespace

QVariant QQuickAction1::shortcut() const
{
#if QT_CONFIG(shortcut)
    return m_shortcut.toString(QKeySequence::NativeText);
#else
    return QString();
#endif
}

void QQuickAction1::setShortcut(const QVariant &arg)
{
#if QT_CONFIG(shortcut)
    QKeySequence sequence;
    if (arg.type() == QVariant::Int)
        sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(arg.toInt()));
    else
        sequence = QKeySequence::fromString(arg.toString());

    if (sequence == m_shortcut)
        return;

    if (!m_shortcut.isEmpty())
        QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(0, this, m_shortcut);

    m_shortcut = sequence;

    if (!m_shortcut.isEmpty()) {
        Qt::ShortcutContext context = Qt::WindowShortcut;
        QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, m_shortcut, context, qShortcutContextMatcher);
    }
    emit shortcutChanged(shortcut());
#endif // QT_CONFIG(shortcut)
}

void QQuickAction1::setMnemonicFromText(const QString &text)
{
#if QT_CONFIG(shortcut)
    QKeySequence sequence = QKeySequence::mnemonic(text);
    if (m_mnemonic == sequence)
        return;

    if (!m_mnemonic.isEmpty())
        QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(0, this, m_mnemonic);

    m_mnemonic = sequence;

    if (!m_mnemonic.isEmpty()) {
        Qt::ShortcutContext context = Qt::WindowShortcut;
        QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, m_mnemonic, context, qMnemonicContextMatcher);
    }
#endif // QT_CONFIG(shortcut)
}

void QQuickAction1::setIconSource(const QUrl &iconSource)
{
    if (iconSource == m_iconSource)
        return;

    m_iconSource = iconSource;
    if (m_iconName.isEmpty() || m_icon.isNull()) {
        QString fileString = QQmlFile::urlToLocalFileOrQrc(iconSource);
        m_icon = QIcon(fileString);

        emit iconChanged();
    }
    emit iconSourceChanged();
}

QString QQuickAction1::iconName() const
{
    return m_iconName;
}

void QQuickAction1::setIconName(const QString &iconName)
{
    if (iconName == m_iconName)
        return;
    m_iconName = iconName;
    m_icon = QIcon::fromTheme(m_iconName, QIcon(QQmlFile::urlToLocalFileOrQrc(m_iconSource)));
    emit iconNameChanged();
    emit iconChanged();
}

void QQuickAction1::setTooltip(const QString &arg)
{
    if (m_tooltip != arg) {
        m_tooltip = arg;
        emit tooltipChanged(arg);
    }
}

void QQuickAction1::setEnabled(bool e)
{
    if (e == m_enabled)
        return;
    m_enabled = e;

    emit enabledChanged();
}

void QQuickAction1::setCheckable(bool c)
{
    if (c == m_checkable)
        return;
    m_checkable = c;
    emit checkableChanged();

    // Setting checkable to false will show checked as false, while setting checkable to
    // true will reveal checked's value again. If checked's internal value is true, we send
    // the signal to notify its visible value.
    if (m_checked)
        emit toggled(m_checkable);
}

void QQuickAction1::setChecked(bool c)
{
    if (c == m_checked)
        return;
    m_checked = c;

    // Its value shows as false while checkable is false. See also comment in setCheckable().
    if (m_checkable)
        emit toggled(m_checked);
}

QQuickExclusiveGroup1 *QQuickAction1::exclusiveGroup() const
{
    return m_exclusiveGroup.data();
}

void QQuickAction1::setExclusiveGroup(QQuickExclusiveGroup1 *eg)
{
    if (m_exclusiveGroup == eg)
        return;

    if (m_exclusiveGroup)
        m_exclusiveGroup->unbindCheckable(this);
    m_exclusiveGroup = eg;
    if (m_exclusiveGroup)
        m_exclusiveGroup->bindCheckable(this);

    emit exclusiveGroupChanged();
}

bool QQuickAction1::event(QEvent *e)
{
#if QT_CONFIG(shortcut)
    if (!m_enabled)
        return false;

    if (e->type() != QEvent::Shortcut)
        return false;

    QShortcutEvent *se = static_cast<QShortcutEvent *>(e);

    Q_ASSERT_X(se->key() == m_shortcut || se->key() == m_mnemonic,
               "QQuickAction::event",
               "Received shortcut event from incorrect shortcut");
    if (se->isAmbiguous()) {
        qWarning("QQuickAction::event: Ambiguous shortcut overload: %s", se->key().toString(QKeySequence::NativeText).toLatin1().constData());
        return false;
    }

    trigger();

    return true;
#else
    return false;
#endif // QT_CONFIG(shortcut)
}

void QQuickAction1::trigger(QObject *source)
{
    if (!m_enabled)
        return;

    if (m_checkable && !(m_checked && m_exclusiveGroup))
        setChecked(!m_checked);

    emit triggered(source);
}

QT_END_NAMESPACE
