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

    QQuickControlPrivate::hideOldItem(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
