/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later 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 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickmenuitem_p.h"
#include "qquickmenuitem_p_p.h"
#include "qquickmenu_p.h"
#include "qquickdeferredexecute_p_p.h"

#include <QtGui/qpa/qplatformtheme.h>
#include <QtQuick/private/qquickevents_p_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype MenuItem
    \inherits AbstractButton
//!     \instantiates QQuickMenuItem
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-menus
    \brief Presents an item within a Menu.

    MenuItem is a convenience type that implements the AbstractButton API,
    providing a familiar way to respond to menu items being \l triggered, for
    example.

    MenuItem inherits its API from AbstractButton. For instance, you can set
    \l {AbstractButton::text}{text} and \l {Icons in Qt Quick Controls}{icon}
    using the AbstractButton API.

    \code
    Button {
        id: fileButton
        text: "File"
        onClicked: menu.open()

        Menu {
            id: menu

            MenuItem {
                text: "New..."
                onTriggered: document.reset()
            }
            MenuItem {
                text: "Open..."
                onTriggered: openDialog.open()
            }
            MenuItem {
                text: "Save"
                onTriggered: saveDialog.open()
            }
        }
    }
    \endcode

    \sa {Customizing Menu}, Menu, {Menu Controls}
*/

void QQuickMenuItemPrivate::setMenu(QQuickMenu *newMenu)
{
    Q_Q(QQuickMenuItem);
    if (menu == newMenu)
        return;

    menu = newMenu;
    emit q->menuChanged();
}

void QQuickMenuItemPrivate::setSubMenu(QQuickMenu *newSubMenu)
{
    Q_Q(QQuickMenuItem);
    if (subMenu == newSubMenu)
        return;

    if (subMenu) {
        QObject::disconnect(subMenu, &QQuickMenu::titleChanged, q, &QQuickAbstractButton::setText);
        QObjectPrivate::disconnect(subMenu, &QQuickPopup::enabledChanged, this, &QQuickMenuItemPrivate::updateEnabled);
    }

    if (newSubMenu) {
        QObject::connect(newSubMenu, &QQuickMenu::titleChanged, q, &QQuickAbstractButton::setText);
        QObjectPrivate::connect(newSubMenu, &QQuickPopup::enabledChanged, this, &QQuickMenuItemPrivate::updateEnabled);
        q->setText(newSubMenu->title());
    }

    subMenu = newSubMenu;
    updateEnabled();
    emit q->subMenuChanged();
}

void QQuickMenuItemPrivate::updateEnabled()
{
    Q_Q(QQuickMenuItem);
    q->setEnabled(subMenu && subMenu->isEnabled());
}

static inline QString arrowName() { return QStringLiteral("arrow"); }

void QQuickMenuItemPrivate::cancelArrow()
{
    Q_Q(QQuickAbstractButton);
    quickCancelDeferred(q, arrowName());
}

void QQuickMenuItemPrivate::executeArrow(bool complete)
{
    Q_Q(QQuickMenuItem);
    if (arrow.wasExecuted())
        return;

    if (!arrow || complete)
        quickBeginDeferred(q, arrowName(), arrow);
    if (complete)
        quickCompleteDeferred(q, arrowName(), arrow);
}

bool QQuickMenuItemPrivate::acceptKeyClick(Qt::Key key) const
{
    return key == Qt::Key_Space || key == Qt::Key_Return || key == Qt::Key_Enter;
}

/*!
    \qmlsignal void QtQuick.Controls::MenuItem::triggered()

    This signal is emitted when the menu item is triggered by the user.
*/

QQuickMenuItem::QQuickMenuItem(QQuickItem *parent)
    : QQuickAbstractButton(*(new QQuickMenuItemPrivate), parent)
{
    connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuItem::triggered);
}

/*!
    \qmlproperty bool QtQuick.Controls::MenuItem::highlighted

    This property holds whether the menu item is highlighted by the user.

    A menu item can be highlighted by mouse hover or keyboard navigation.

    The default value is \c false.

    \sa Menu::currentIndex
*/
bool QQuickMenuItem::isHighlighted() const
{
    Q_D(const QQuickMenuItem);
    return d->highlighted;
}

void QQuickMenuItem::setHighlighted(bool highlighted)
{
    Q_D(QQuickMenuItem);
    if (highlighted == d->highlighted)
        return;

    d->highlighted = highlighted;
    emit highlightedChanged();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty Item QtQuick.Controls::MenuItem::arrow

    This property holds the sub-menu arrow item.

    \sa {Customizing Menu}
*/
QQuickItem *QQuickMenuItem::arrow() const
{
    QQuickMenuItemPrivate *d = const_cast<QQuickMenuItemPrivate *>(d_func());
    if (!d->arrow)
        d->executeArrow();
    return d->arrow;
}

void QQuickMenuItem::setArrow(QQuickItem *arrow)
{
    Q_D(QQuickMenuItem);
    if (d->arrow == arrow)
        return;

    if (!d->arrow.isExecuting())
        d->cancelArrow();

    delete d->arrow;
    d->arrow = arrow;
    if (arrow && !arrow->parentItem())
        arrow->setParentItem(this);
    if (!d->arrow.isExecuting())
        emit arrowChanged();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty Menu QtQuick.Controls::MenuItem::menu
    \readonly

    This property holds the menu that contains this menu item,
    or \c null if the item is not in a menu.
*/
QQuickMenu *QQuickMenuItem::menu() const
{
    Q_D(const QQuickMenuItem);
    return d->menu;
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty Menu QtQuick.Controls::MenuItem::subMenu
    \readonly

    This property holds the sub-menu that this item presents in
    the parent menu, or \c null if this item is not a sub-menu item.
*/
QQuickMenu *QQuickMenuItem::subMenu() const
{
    Q_D(const QQuickMenuItem);
    return d->subMenu;
}

void QQuickMenuItem::componentComplete()
{
    Q_D(QQuickMenuItem);
    d->executeArrow(true);
    QQuickAbstractButton::componentComplete();
}

QFont QQuickMenuItem::defaultFont() const
{
    return QQuickTheme::font(QQuickTheme::Menu);
}

QPalette QQuickMenuItem::defaultPalette() const
{
    return QQuickTheme::palette(QQuickTheme::Menu);
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickMenuItem::accessibleRole() const
{
    return QAccessible::MenuItem;
}
#endif

QT_END_NAMESPACE
