/****************************************************************************
**
** 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 "qquickmenu_p.h"
#include "qquickmenu_p_p.h"
#include "qquickmenuitem_p_p.h"
#include "qquickmenubaritem_p.h"
#include "qquickmenubar_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickpopuppositioner_p_p.h"
#include "qquickaction_p.h"

#include <QtGui/qevent.h>
#include <QtGui/qcursor.h>
#include <QtGui/qpa/qplatformintegration.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQml/private/qqmlengine_p.h>
#include <QtQml/private/qv4scopedvalue_p.h>
#include <QtQml/private/qv4variantobject_p.h>
#include <QtQml/private/qv4qobjectwrapper_p.h>
#include <private/qqmlobjectmodel_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
#include <QtQuick/private/qquickitemview_p.h>
#include <QtQuick/private/qquickevents_p_p.h>
#include <QtQuick/private/qquickwindow_p.h>

QT_BEGIN_NAMESPACE

// copied from qfusionstyle.cpp
static const int SUBMENU_DELAY = 225;

/*!
    \qmltype Menu
    \inherits Popup
//!     \instantiates QQuickMenu
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-menus
    \ingroup qtquickcontrols2-popups
    \brief Menu popup that can be used as a context menu or popup menu.

    \image qtquickcontrols2-menu.png

    Menu has two main use cases:
    \list
        \li Context menus; for example, a menu that is shown after right clicking
        \li Popup menus; for example, a menu that is shown after clicking a button
    \endlist

    When used as a context menu, the recommended way of opening the menu is to call
    \l popup(). Unless a position is explicitly specified, the menu is positioned at
    the mouse cursor on desktop platforms that have a mouse cursor available, and
    otherwise centered over its parent item.

    \code
    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton
        onClicked: {
            if (mouse.button === Qt.RightButton)
                contextMenu.popup()
        }
        onPressAndHold: {
            if (mouse.source === Qt.MouseEventNotSynthesized)
                contextMenu.popup()
        }

        Menu {
            id: contextMenu
            MenuItem { text: "Cut" }
            MenuItem { text: "Copy" }
            MenuItem { text: "Paste" }
        }
    }
    \endcode

    When used as a popup menu, it is easiest to specify the position by specifying
    the desired \l {Popup::}{x} and \l {Popup::}{y} coordinates using the respective
    properties, and call \l {Popup::}{open()} to open the menu.

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

        Menu {
            id: menu
            y: fileButton.height

            MenuItem {
                text: "New..."
            }
            MenuItem {
                text: "Open..."
            }
            MenuItem {
                text: "Save"
            }
        }
    }
    \endcode

    Since QtQuick.Controls 2.3 (Qt 5.10), it is also possible to create sub-menus
    and declare Action objects inside Menu:

    \code
    Menu {
        Action { text: "Cut" }
        Action { text: "Copy" }
        Action { text: "Paste" }

        MenuSeparator { }

        Menu {
            title: "Find/Replace"
            Action { text: "Find Next" }
            Action { text: "Find Previous" }
            Action { text: "Replace" }
        }
    }
    \endcode

    Sub-menus are \l {cascade}{cascading} by default on desktop platforms
    that have a mouse cursor available. Non-cascading menus are shown one
    menu at a time, and centered over the parent menu.

    Typically, menu items are statically declared as children of the menu, but
    Menu also provides API to \l {addItem}{add}, \l {insertItem}{insert},
    \l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The
    items in a menu can be accessed using \l itemAt() or
    \l {Popup::}{contentChildren}.

    Although \l {MenuItem}{MenuItems} are most commonly used with Menu, it can
    contain any type of item.

    \section1 Margins

    As it is inherited from Popup, Menu supports \l {Popup::}{margins}. By
    default, all of the built-in styles specify \c 0 for Menu's margins to
    ensure that the menu is kept within the bounds of the window. To allow a
    menu to go outside of the window (to animate it moving into view, for
    example), set the margins property to \c -1.

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

/*!
    \qmlproperty bool QtQuick.Controls::Menu::focus

    This property holds whether the popup wants focus.

    When the popup actually receives focus, \l{Popup::}{activeFocus}
    will be \c true. For more information, see
    \l {Keyboard Focus in Qt Quick}.

    The default value is \c false.

    \sa activeFocus
*/

static const QQuickPopup::ClosePolicy cascadingSubMenuClosePolicy = QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent;

static bool shouldCascade()
{
#if QT_CONFIG(cursor)
    return QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
#else
    return false;
#endif
}

class QQuickMenuPositioner : public QQuickPopupPositioner
{
public:
    QQuickMenuPositioner(QQuickMenu *menu) : QQuickPopupPositioner(menu) { }

    void reposition() override;
};

QQuickMenuPrivate::QQuickMenuPrivate()
{
    Q_Q(QQuickMenu);
    cascade = shouldCascade();
    contentModel = new QQmlObjectModel(q);
}

QQuickItem *QQuickMenuPrivate::itemAt(int index) const
{
    return qobject_cast<QQuickItem *>(contentModel->get(index));
}

void QQuickMenuPrivate::insertItem(int index, QQuickItem *item)
{
    contentData.append(item);
    item->setParentItem(contentItem);
    if (qobject_cast<QQuickItemView *>(contentItem))
        QQuickItemPrivate::get(item)->setCulled(true); // QTBUG-53262
    if (complete)
        resizeItem(item);
    QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent);
    QQuickItemPrivate::get(item)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Width);
    contentModel->insert(index, item);

    QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item);
    if (menuItem) {
        Q_Q(QQuickMenu);
        QQuickMenuItemPrivate::get(menuItem)->setMenu(q);
        if (QQuickMenu *subMenu = menuItem->subMenu())
            QQuickMenuPrivate::get(subMenu)->setParentMenu(q);
        QObjectPrivate::connect(menuItem, &QQuickMenuItem::triggered, this, &QQuickMenuPrivate::onItemTriggered);
        QObjectPrivate::connect(menuItem, &QQuickItem::activeFocusChanged, this, &QQuickMenuPrivate::onItemActiveFocusChanged);
        QObjectPrivate::connect(menuItem, &QQuickControl::hoveredChanged, this, &QQuickMenuPrivate::onItemHovered);
    }
}

void QQuickMenuPrivate::moveItem(int from, int to)
{
    contentModel->move(from, to);
}

void QQuickMenuPrivate::removeItem(int index, QQuickItem *item)
{
    contentData.removeOne(item);

    QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent);
    QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
    item->setParentItem(nullptr);
    contentModel->remove(index);

    QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item);
    if (menuItem) {
        QQuickMenuItemPrivate::get(menuItem)->setMenu(nullptr);
        if (QQuickMenu *subMenu = menuItem->subMenu())
            QQuickMenuPrivate::get(subMenu)->setParentMenu(nullptr);
        QObjectPrivate::disconnect(menuItem, &QQuickMenuItem::triggered, this, &QQuickMenuPrivate::onItemTriggered);
        QObjectPrivate::disconnect(menuItem, &QQuickItem::activeFocusChanged, this, &QQuickMenuPrivate::onItemActiveFocusChanged);
        QObjectPrivate::disconnect(menuItem, &QQuickControl::hoveredChanged, this, &QQuickMenuPrivate::onItemHovered);
    }
}

QQuickItem *QQuickMenuPrivate::beginCreateItem()
{
    Q_Q(QQuickMenu);
    if (!delegate)
        return nullptr;

    QQmlContext *creationContext = delegate->creationContext();
    if (!creationContext)
        creationContext = qmlContext(q);
    QQmlContext *context = new QQmlContext(creationContext, q);
    context->setContextObject(q);

    QObject *object = delegate->beginCreate(context);
    QQuickItem *item = qobject_cast<QQuickItem *>(object);
    if (!item)
        delete object;

    QQml_setParent_noEvent(item, q);

    return item;
}

void QQuickMenuPrivate::completeCreateItem()
{
    if (!delegate)
        return;

    delegate->completeCreate();
}

QQuickItem *QQuickMenuPrivate::createItem(QQuickMenu *menu)
{
    QQuickItem *item = beginCreateItem();
    if (QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item))
        QQuickMenuItemPrivate::get(menuItem)->setSubMenu(menu);
    completeCreateItem();
    return item;
}

QQuickItem *QQuickMenuPrivate::createItem(QQuickAction *action)
{
    QQuickItem *item = beginCreateItem();
    if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item))
        button->setAction(action);
    completeCreateItem();
    return item;
}

void QQuickMenuPrivate::resizeItem(QQuickItem *item)
{
    if (!item || !contentItem)
        return;

    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
    if (!p->widthValid) {
        item->setWidth(contentItem->width());
        p->widthValid = false;
    }
}

void QQuickMenuPrivate::resizeItems()
{
    if (!contentModel)
        return;

    for (int i = 0; i < contentModel->count(); ++i)
        resizeItem(itemAt(i));
}

void QQuickMenuPrivate::itemChildAdded(QQuickItem *, QQuickItem *child)
{
    // add dynamically reparented items (eg. by a Repeater)
    if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child))
        insertItem(contentModel->count(), child);
}

void QQuickMenuPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
{
    // remove dynamically unparented items (eg. by a Repeater)
    if (!parent)
        removeItem(contentModel->indexOf(item, nullptr), item);
}

void QQuickMenuPrivate::itemSiblingOrderChanged(QQuickItem *)
{
    // reorder the restacked items (eg. by a Repeater)
    Q_Q(QQuickMenu);
    QList<QQuickItem *> siblings = contentItem->childItems();

    int to = 0;
    for (int i = 0; i < siblings.count(); ++i) {
        QQuickItem* sibling = siblings.at(i);
        if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner())
            continue;
        int index = contentModel->indexOf(sibling, nullptr);
        q->moveItem(index, to++);
    }
}

void QQuickMenuPrivate::itemDestroyed(QQuickItem *item)
{
    QQuickPopupPrivate::itemDestroyed(item);
    int index = contentModel->indexOf(item, nullptr);
    if (index != -1)
        removeItem(index, item);
}

void QQuickMenuPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &)
{
    if (!complete)
        return;

    if (item == contentItem) {
        // The contentItem's geometry changed, so resize any items
        // that don't have explicit widths set so that they fill the width of the menu.
        resizeItems();
    } else {
        // The geometry of an item in the menu changed. If the item
        // doesn't have an explicit width set, make it fill the width of the menu.
        resizeItem(item);
    }
}

QQuickPopupPositioner *QQuickMenuPrivate::getPositioner()
{
    Q_Q(QQuickMenu);
    if (!positioner)
        positioner = new QQuickMenuPositioner(q);
    return positioner;
}

void QQuickMenuPositioner::reposition()
{
    QQuickMenu *menu = static_cast<QQuickMenu *>(popup());
    QQuickMenuPrivate *p = QQuickMenuPrivate::get(menu);
    if (p->parentMenu) {
        if (p->cascade) {
            if (p->popupItem->isMirrored())
                menu->setPosition(QPointF(-menu->width() - p->parentMenu->leftPadding() + menu->overlap(), -menu->topPadding()));
            else if (p->parentItem)
                menu->setPosition(QPointF(p->parentItem->width() + p->parentMenu->rightPadding() - menu->overlap(), -menu->topPadding()));
        } else {
            menu->setPosition(QPointF(p->parentMenu->x() + (p->parentMenu->width() - menu->width()) / 2,
                                      p->parentMenu->y() + (p->parentMenu->height() - menu->height()) / 2));
        }
    }
    QQuickPopupPositioner::reposition();
}

bool QQuickMenuPrivate::prepareEnterTransition()
{
    Q_Q(QQuickMenu);
    if (parentMenu && !cascade)
        parentMenu->close();

    // If a cascading sub-menu doesn't have enough space to open on
    // the right, it flips on the other side of the parent menu.
    allowHorizontalFlip = cascade && parentMenu;

    if (!QQuickPopupPrivate::prepareEnterTransition())
        return false;

    if (!hasClosePolicy) {
        if (cascade && parentMenu)
            closePolicy = cascadingSubMenuClosePolicy;
        else
            q->resetClosePolicy();
    }
    return true;
}

bool QQuickMenuPrivate::prepareExitTransition()
{
    if (!QQuickPopupPrivate::prepareExitTransition())
        return false;

    stopHoverTimer();

    QQuickMenu *subMenu = currentSubMenu();
    while (subMenu) {
        QPointer<QQuickMenuItem> currentSubMenuItem = QQuickMenuPrivate::get(subMenu)->currentItem;
        subMenu->close();
        subMenu = currentSubMenuItem ? currentSubMenuItem->subMenu() : nullptr;
    }
    return true;
}

bool QQuickMenuPrivate::blockInput(QQuickItem *item, const QPointF &point) const
{
    // keep the parent menu open when a cascading sub-menu (this menu) is interacted with
    return (cascade && parentMenu && contains(point)) || QQuickPopupPrivate::blockInput(item, point);
}

void QQuickMenuPrivate::onItemHovered()
{
    Q_Q(QQuickMenu);
    QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
    if (!button || !button->isHovered() || QQuickAbstractButtonPrivate::get(button)->touchId != -1)
        return;

    QQuickMenuItem *oldCurrentItem = currentItem;

    int index = contentModel->indexOf(button, nullptr);
    if (index != -1) {
        setCurrentIndex(index, Qt::OtherFocusReason);
        if (oldCurrentItem != currentItem) {
            if (oldCurrentItem) {
                QQuickMenu *subMenu = oldCurrentItem->subMenu();
                if (subMenu)
                    subMenu->close();
            }
            if (currentItem) {
                QQuickMenu *subMenu = currentItem->menu();
                if (subMenu && subMenu->cascade())
                    startHoverTimer();
            }
        }
    }
}

void QQuickMenuPrivate::onItemTriggered()
{
    Q_Q(QQuickMenu);
    QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(q->sender());
    if (!item)
        return;

    if (QQuickMenu *subMenu = item->subMenu()) {
        auto subMenuPrivate = QQuickMenuPrivate::get(subMenu);
        subMenu->popup(subMenuPrivate->firstEnabledMenuItem());
    } else {
        q->dismiss();
    }
}

void QQuickMenuPrivate::onItemActiveFocusChanged()
{
    Q_Q(QQuickMenu);
    QQuickItem *item = qobject_cast<QQuickItem*>(q->sender());
    if (!item->hasActiveFocus())
        return;

    int indexOfItem = contentModel->indexOf(item, nullptr);
    QQuickControl *control = qobject_cast<QQuickControl *>(item);
    setCurrentIndex(indexOfItem, control ? control->focusReason() : Qt::OtherFocusReason);
}

QQuickMenu *QQuickMenuPrivate::currentSubMenu() const
{
    if (!currentItem)
        return nullptr;

    return currentItem->subMenu();
}

void QQuickMenuPrivate::setParentMenu(QQuickMenu *parent)
{
    Q_Q(QQuickMenu);
    if (parentMenu == parent)
        return;

    if (parentMenu) {
        QObject::disconnect(parentMenu.data(), &QQuickMenu::cascadeChanged, q, &QQuickMenu::setCascade);
        disconnect(parentMenu.data(), &QQuickMenu::parentChanged, this, &QQuickMenuPrivate::resolveParentItem);
    }
    if (parent) {
        QObject::connect(parent, &QQuickMenu::cascadeChanged, q, &QQuickMenu::setCascade);
        connect(parent, &QQuickMenu::parentChanged, this, &QQuickMenuPrivate::resolveParentItem);
    }

    parentMenu = parent;
    q->resetCascade();
    resolveParentItem();
}

static QQuickItem *findParentMenuItem(QQuickMenu *subMenu)
{
    QQuickMenu *menu = QQuickMenuPrivate::get(subMenu)->parentMenu;
    for (int i = 0; i < QQuickMenuPrivate::get(menu)->contentModel->count(); ++i) {
        QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(menu->itemAt(i));
        if (item && item->subMenu() == subMenu)
            return item;
    }
    return nullptr;
}

void QQuickMenuPrivate::resolveParentItem()
{
    Q_Q(QQuickMenu);
    if (!parentMenu)
        q->resetParentItem();
    else if (!cascade)
        q->setParentItem(parentMenu->parentItem());
    else
        q->setParentItem(findParentMenuItem(q));
}

void QQuickMenuPrivate::propagateKeyEvent(QKeyEvent *event)
{
    if (QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(parentItem)) {
        if (QQuickMenu *menu = menuItem->menu())
            QQuickMenuPrivate::get(menu)->propagateKeyEvent(event);
    } else if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(parentItem)) {
        if (QQuickMenuBar *menuBar = menuBarItem->menuBar()) {
            event->accept();
            QCoreApplication::sendEvent(menuBar, event);
        }
    }
}

void QQuickMenuPrivate::startHoverTimer()
{
    Q_Q(QQuickMenu);
    stopHoverTimer();
    hoverTimer = q->startTimer(SUBMENU_DELAY);
}

void QQuickMenuPrivate::stopHoverTimer()
{
    Q_Q(QQuickMenu);
    if (!hoverTimer)
        return;

    q->killTimer(hoverTimer);
    hoverTimer = 0;
}

void QQuickMenuPrivate::setCurrentIndex(int index, Qt::FocusReason reason)
{
    Q_Q(QQuickMenu);
    if (currentIndex == index)
        return;

    QQuickMenuItem *newCurrentItem = qobject_cast<QQuickMenuItem *>(itemAt(index));
    if (currentItem != newCurrentItem) {
        stopHoverTimer();
        if (currentItem) {
            currentItem->setHighlighted(false);
            if (!newCurrentItem && window) {
                QQuickItem *focusItem = QQuickItemPrivate::get(contentItem)->subFocusItem;
                if (focusItem)
                    QQuickWindowPrivate::get(window)->clearFocusInScope(contentItem, focusItem, Qt::OtherFocusReason);
            }
        }
        if (newCurrentItem) {
            newCurrentItem->setHighlighted(true);
            newCurrentItem->forceActiveFocus(reason);
        }
        currentItem = newCurrentItem;
    }

    currentIndex = index;
    emit q->currentIndexChanged();
}

bool QQuickMenuPrivate::activateNextItem()
{
    int index = currentIndex;
    int count = contentModel->count();
    while (++index < count) {
        QQuickItem *item = itemAt(index);
        if (!item || !item->activeFocusOnTab() || !item->isEnabled())
            continue;
        setCurrentIndex(index, Qt::TabFocusReason);
        return true;
    }
    return false;
}

bool QQuickMenuPrivate::activatePreviousItem()
{
    int index = currentIndex;
    while (--index >= 0) {
        QQuickItem *item = itemAt(index);
        if (!item || !item->activeFocusOnTab() || !item->isEnabled())
            continue;
        setCurrentIndex(index, Qt::BacktabFocusReason);
        return true;
    }
    return false;
}

QQuickMenuItem *QQuickMenuPrivate::firstEnabledMenuItem() const
{
    for (int i = 0; i < contentModel->count(); ++i) {
        QQuickItem *item = itemAt(i);
        if (!item || !item->isEnabled())
            continue;

        QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item);
        if (!menuItem)
            continue;

        return menuItem;
    }
    return nullptr;
}

void QQuickMenuPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
{
    QQuickMenu *q = qobject_cast<QQuickMenu *>(prop->object);
    QQuickMenuPrivate *p = QQuickMenuPrivate::get(q);

    QQuickItem *item = qobject_cast<QQuickItem *>(obj);
    if (!item) {
        if (QQuickAction *action = qobject_cast<QQuickAction *>(obj))
            item = p->createItem(action);
        else if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj))
            item = p->createItem(menu);
    }

    if (item) {
        if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) {
            QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder);
            item->setParentItem(p->contentItem);
        } else if (p->contentModel->indexOf(item, nullptr) == -1) {
            q->addItem(item);
        }
    } else {
        p->contentData.append(obj);
    }
}

int QQuickMenuPrivate::contentData_count(QQmlListProperty<QObject> *prop)
{
    QQuickMenu *q = static_cast<QQuickMenu *>(prop->object);
    return QQuickMenuPrivate::get(q)->contentData.count();
}

QObject *QQuickMenuPrivate::contentData_at(QQmlListProperty<QObject> *prop, int index)
{
    QQuickMenu *q = static_cast<QQuickMenu *>(prop->object);
    return QQuickMenuPrivate::get(q)->contentData.value(index);
}

void QQuickMenuPrivate::contentData_clear(QQmlListProperty<QObject> *prop)
{
    QQuickMenu *q = static_cast<QQuickMenu *>(prop->object);
    QQuickMenuPrivate::get(q)->contentData.clear();
}

QQuickMenu::QQuickMenu(QObject *parent)
    : QQuickPopup(*(new QQuickMenuPrivate), parent)
{
    Q_D(QQuickMenu);
    setFocus(true);
    connect(d->contentModel, &QQmlObjectModel::countChanged, this, &QQuickMenu::countChanged);
}

/*!
    \qmlmethod Item QtQuick.Controls::Menu::itemAt(int index)

    Returns the item at \a index, or \c null if it does not exist.
*/
QQuickItem *QQuickMenu::itemAt(int index) const
{
    Q_D(const QQuickMenu);
    return d->itemAt(index);
}

/*!
    \qmlmethod void QtQuick.Controls::Menu::addItem(Item item)

    Adds \a item to the end of the list of items.
*/
void QQuickMenu::addItem(QQuickItem *item)
{
    Q_D(QQuickMenu);
    insertItem(d->contentModel->count(), item);
}

/*!
    \qmlmethod void QtQuick.Controls::Menu::insertItem(int index, Item item)

    Inserts \a item at \a index.
*/
void QQuickMenu::insertItem(int index, QQuickItem *item)
{
    Q_D(QQuickMenu);
    if (!item)
        return;
    const int count = d->contentModel->count();
    if (index < 0 || index > count)
        index = count;

    int oldIndex = d->contentModel->indexOf(item, nullptr);
    if (oldIndex != -1) {
        if (oldIndex < index)
            --index;
        if (oldIndex != index)
            d->moveItem(oldIndex, index);
    } else {
        d->insertItem(index, item);
    }
}

/*!
    \qmlmethod void QtQuick.Controls::Menu::moveItem(int from, int to)

    Moves an item \a from one index \a to another.
*/
void QQuickMenu::moveItem(int from, int to)
{
    Q_D(QQuickMenu);
    const int count = d->contentModel->count();
    if (from < 0 || from > count - 1)
        return;
    if (to < 0 || to > count - 1)
        to = count - 1;

    if (from != to)
        d->moveItem(from, to);
}

/*!
    \deprecated
    \qmlmethod void QtQuick.Controls::Menu::removeItem(int index)

    Use Menu::removeItem(Item) or Menu::takeItem(int) instead.
*/
void QQuickMenu::removeItem(const QVariant &var)
{
    if (var.userType() == QMetaType::Nullptr)
        return;

    if (QQuickItem *item = var.value<QQuickItem *>())
        removeItem(item);
    else
        takeItem(var.toInt());
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::removeItem(Item item)

    Removes and destroys the specified \a item.
*/
void QQuickMenu::removeItem(QQuickItem *item)
{
    Q_D(QQuickMenu);
    if (!item)
        return;

    const int index = d->contentModel->indexOf(item, nullptr);
    if (index == -1)
        return;

    d->removeItem(index, item);
    item->deleteLater();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod MenuItem QtQuick.Controls::Menu::takeItem(int index)

    Removes and returns the item at \a index.

    \note The ownership of the item is transferred to the caller.
*/
QQuickItem *QQuickMenu::takeItem(int index)
{
    Q_D(QQuickMenu);
    const int count = d->contentModel->count();
    if (index < 0 || index >= count)
        return nullptr;

    QQuickItem *item = itemAt(index);
    if (item)
        d->removeItem(index, item);
    return item;
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod Menu QtQuick.Controls::Menu::menuAt(int index)

    Returns the sub-menu at \a index, or \c null if the index is not valid or
    there is no sub-menu at the specified index.
*/
QQuickMenu *QQuickMenu::menuAt(int index) const
{
    Q_D(const QQuickMenu);
    QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index));
    if (!item)
        return nullptr;

    return item->subMenu();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::addMenu(Menu menu)

    Adds \a menu as a sub-menu to the end of this menu.
*/
void QQuickMenu::addMenu(QQuickMenu *menu)
{
    Q_D(QQuickMenu);
    insertMenu(d->contentModel->count(), menu);
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::insertMenu(int index, Menu menu)

    Inserts \a menu as a sub-menu at \a index. The index is within all items in the menu.
*/
void QQuickMenu::insertMenu(int index, QQuickMenu *menu)
{
    Q_D(QQuickMenu);
    if (!menu)
        return;

    insertItem(index, d->createItem(menu));
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::removeMenu(Menu menu)

    Removes and destroys the specified \a menu.
*/
void QQuickMenu::removeMenu(QQuickMenu *menu)
{
    Q_D(QQuickMenu);
    if (!menu)
        return;

    const int count = d->contentModel->count();
    for (int i = 0; i < count; ++i) {
        QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(i));
        if (!item || item->subMenu() != menu)
            continue;

        removeItem(item);
        break;
    }

    menu->deleteLater();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod Menu QtQuick.Controls::Menu::takeMenu(int index)

    Removes and returns the menu at \a index. The index is within all items in the menu.

    \note The ownership of the menu is transferred to the caller.
*/
QQuickMenu *QQuickMenu::takeMenu(int index)
{
    Q_D(QQuickMenu);
    QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index));
    if (!item)
        return nullptr;

    QQuickMenu *subMenu = item->subMenu();
    if (!subMenu)
        return nullptr;

    d->removeItem(index, item);
    item->deleteLater();
    return subMenu;
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod Action QtQuick.Controls::Menu::actionAt(int index)

    Returns the action at \a index, or \c null if the index is not valid or
    there is no action at the specified index.
*/
QQuickAction *QQuickMenu::actionAt(int index) const
{
    Q_D(const QQuickMenu);
    QQuickAbstractButton *item = qobject_cast<QQuickAbstractButton *>(d->itemAt(index));
    if (!item)
        return nullptr;

    return item->action();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::addAction(Action action)

    Adds \a action to the end of this menu.
*/
void QQuickMenu::addAction(QQuickAction *action)
{
    Q_D(QQuickMenu);
    insertAction(d->contentModel->count(), action);
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::insertAction(int index, Action action)

    Inserts \a action at \a index. The index is within all items in the menu.
*/
void QQuickMenu::insertAction(int index, QQuickAction *action)
{
    Q_D(QQuickMenu);
    if (!action)
        return;

    insertItem(index, d->createItem(action));
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::removeAction(Action action)

    Removes and destroys the specified \a action.
*/
void QQuickMenu::removeAction(QQuickAction *action)
{
    Q_D(QQuickMenu);
    if (!action)
        return;

    const int count = d->contentModel->count();
    for (int i = 0; i < count; ++i) {
        QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(i));
        if (!item || item->action() != action)
            continue;

        removeItem(item);
        break;
    }

    action->deleteLater();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod Action QtQuick.Controls::Menu::takeAction(int index)

    Removes and returns the action at \a index. The index is within all items in the menu.

    \note The ownership of the action is transferred to the caller.
*/
QQuickAction *QQuickMenu::takeAction(int index)
{
    Q_D(QQuickMenu);
    QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index));
    if (!item)
        return nullptr;

    QQuickAction *action = item->action();
    if (!action)
        return nullptr;

    d->removeItem(index, item);
    item->deleteLater();
    return action;
}

/*!
    \qmlproperty model QtQuick.Controls::Menu::contentModel
    \readonly

    This property holds the model used to display menu items.

    The content model is provided for visualization purposes. It can be assigned
    as a model to a content item that presents the contents of the menu.

    \code
    Menu {
        id: menu
        contentItem: ListView {
            model: menu.contentModel
        }
    }
    \endcode

    The model allows menu items to be statically declared as children of the
    menu.
*/
QVariant QQuickMenu::contentModel() const
{
    Q_D(const QQuickMenu);
    return QVariant::fromValue(d->contentModel);
}

/*!
    \qmlproperty list<Object> QtQuick.Controls::Menu::contentData
    \default

    This property holds the list of content data.

    The list contains all objects that have been declared in QML as children
    of the menu, and also items that have been dynamically added or
    inserted using the \l addItem() and \l insertItem() methods, respectively.

    \note Unlike \c contentChildren, \c contentData does include non-visual QML
    objects. It is not re-ordered when items are inserted or moved.

    \sa Item::data, {Popup::}{contentChildren}
*/
QQmlListProperty<QObject> QQuickMenu::contentData()
{
    Q_D(QQuickMenu);
    if (!d->contentItem)
        QQuickControlPrivate::get(d->popupItem)->executeContentItem();
    return QQmlListProperty<QObject>(this, nullptr,
        QQuickMenuPrivate::contentData_append,
        QQuickMenuPrivate::contentData_count,
        QQuickMenuPrivate::contentData_at,
        QQuickMenuPrivate::contentData_clear);
}

/*!
    \qmlproperty string QtQuick.Controls::Menu::title

    This property holds the title for the menu.

    The title of a menu is often displayed in the text of a menu item when the
    menu is a submenu, and in the text of a tool button when it is in a
    menubar.
*/
QString QQuickMenu::title() const
{
    Q_D(const QQuickMenu);
    return d->title;
}

void QQuickMenu::setTitle(QString &title)
{
    Q_D(QQuickMenu);
    if (title == d->title)
        return;
    d->title = title;
    emit titleChanged(title);
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty bool QtQuick.Controls::Menu::cascade

    This property holds whether the menu cascades its sub-menus.

    The default value is platform-specific. Menus are cascading by default on
    desktop platforms that have a mouse cursor available. Non-cascading menus
    are shown one menu at a time, and centered over the parent menu.

    \note Changing the value of the property has no effect while the menu is open.

    \sa overlap
*/
bool QQuickMenu::cascade() const
{
    Q_D(const QQuickMenu);
    return d->cascade;
}

void QQuickMenu::setCascade(bool cascade)
{
    Q_D(QQuickMenu);
    if (d->cascade == cascade)
        return;
    d->cascade = cascade;
    if (d->parentMenu)
        d->resolveParentItem();
    emit cascadeChanged(cascade);
}

void QQuickMenu::resetCascade()
{
    Q_D(QQuickMenu);
    if (d->parentMenu)
        setCascade(d->parentMenu->cascade());
    else
        setCascade(shouldCascade());
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty real QtQuick.Controls::Menu::overlap

    This property holds the amount of pixels by which the menu horizontally overlaps its parent menu.

    The property only has effect when the menu is used as a cascading sub-menu.

    The default value is style-specific.

    \note Changing the value of the property has no effect while the menu is open.

    \sa cascade
*/
qreal QQuickMenu::overlap() const
{
    Q_D(const QQuickMenu);
    return d->overlap;
}

void QQuickMenu::setOverlap(qreal overlap)
{
    Q_D(QQuickMenu);
    if (d->overlap == overlap)
        return;
    d->overlap = overlap;
    emit overlapChanged();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty Component QtQuick.Controls::Menu::delegate

    This property holds the component that is used to create items
    to present actions.

    \code
    Menu {
        Action { text: "Cut" }
        Action { text: "Copy" }
        Action { text: "Paste" }
    }
    \endcode

    \sa Action
*/
QQmlComponent *QQuickMenu::delegate() const
{
    Q_D(const QQuickMenu);
    return d->delegate;
}

void QQuickMenu::setDelegate(QQmlComponent *delegate)
{
    Q_D(QQuickMenu);
    if (d->delegate == delegate)
        return;

    d->delegate = delegate;
    emit delegateChanged();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty int QtQuick.Controls::Menu::currentIndex

    This property holds the index of the currently highlighted item.

    Menu items can be highlighted by mouse hover or keyboard navigation.

    \sa MenuItem::highlighted
*/
int QQuickMenu::currentIndex() const
{
    Q_D(const QQuickMenu);
    return d->currentIndex;
}

void QQuickMenu::setCurrentIndex(int index)
{
    Q_D(QQuickMenu);
    d->setCurrentIndex(index, Qt::OtherFocusReason);
}

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

    This property holds the number of items.
*/
int QQuickMenu::count() const
{
    Q_D(const QQuickMenu);
    return d->contentModel->count();
}

void QQuickMenu::popup(QQuickItem *menuItem)
{
    Q_D(QQuickMenu);
    // No position has been explicitly specified, so position the menu at the mouse cursor
    // on desktop platforms that have a mouse cursor available and support multiple windows.
    QQmlNullableValue<QPointF> pos;
#if QT_CONFIG(cursor)
    if (d->parentItem && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows))
        pos = d->parentItem->mapFromGlobal(QCursor::pos());
#endif

    // As a fallback, center the menu over its parent item.
    if (pos.isNull && d->parentItem)
        pos = QPointF((d->parentItem->width() - width()) / 2, (d->parentItem->height() - height()) / 2);

    popup(pos.isNull ? QPointF() : pos.value, menuItem);
}

void QQuickMenu::popup(const QPointF &pos, QQuickItem *menuItem)
{
    Q_D(QQuickMenu);
    qreal offset = 0;
#if QT_CONFIG(cursor)
    if (menuItem)
        offset = d->popupItem->mapFromItem(menuItem, QPointF(0, 0)).y();
#endif
    setPosition(pos - QPointF(0, offset));

    if (menuItem)
        d->setCurrentIndex(d->contentModel->indexOf(menuItem, nullptr), Qt::PopupFocusReason);
    open();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::popup(MenuItem item = null)
    \qmlmethod void QtQuick.Controls::Menu::popup(Item parent, MenuItem item = null)

    Opens the menu at the mouse cursor on desktop platforms that have a mouse cursor
    available, and otherwise centers the menu over its \a parent item.

    The menu can be optionally aligned to a specific menu \a item.

    \sa Popup::open()
*/

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::popup(point pos, MenuItem item = null)
    \qmlmethod void QtQuick.Controls::Menu::popup(Item parent, point pos, MenuItem item = null)

    Opens the menu at the specified position \a pos in the popups coordinate system,
    that is, a coordinate relative to its \a parent item.

    The menu can be optionally aligned to a specific menu \a item.

    \sa Popup::open()
*/

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::popup(real x, real y, MenuItem item = null)
    \qmlmethod void QtQuick.Controls::Menu::popup(Item parent, real x, real y, MenuItem item = null)

    Opens the menu at the specified position \a x, \a y in the popups coordinate system,
    that is, a coordinate relative to its \a parent item.

    The menu can be optionally aligned to a specific menu \a item.

    \sa dismiss(), Popup::open()
*/
void QQuickMenu::popup(QQmlV4Function *args)
{
    Q_D(QQuickMenu);
    const int len = args->length();
    if (len > 4) {
        args->v4engine()->throwTypeError();
        return;
    }

    QV4::ExecutionEngine *v4 = args->v4engine();
    QV4::Scope scope(v4);

    QQmlNullableValue<QPointF> pos;
    QQuickItem *menuItem = nullptr;
    QQuickItem *parentItem = nullptr;

    if (len > 0) {
        // Item parent
        QV4::ScopedValue firstArg(scope, (*args)[0]);
        if (const QV4::QObjectWrapper *obj = firstArg->as<QV4::QObjectWrapper>()) {
            QQuickItem *item = qobject_cast<QQuickItem *>(obj->object());
            if (item && !d->popupItem->isAncestorOf(item))
                parentItem = item;
        } else if (firstArg->isUndefined()) {
            resetParentItem();
            parentItem = d->parentItem;
        }

        // MenuItem item
        QV4::ScopedValue lastArg(scope, (*args)[len - 1]);
        if (const QV4::QObjectWrapper *obj = lastArg->as<QV4::QObjectWrapper>()) {
            QQuickItem *item = qobject_cast<QQuickItem *>(obj->object());
            if (item && d->popupItem->isAncestorOf(item))
                menuItem = item;
        }
    }

    if (len >= 3 || (!parentItem && len >= 2)) {
        // real x, real y
        QV4::ScopedValue xArg(scope, (*args)[parentItem ? 1 : 0]);
        QV4::ScopedValue yArg(scope, (*args)[parentItem ? 2 : 1]);
        if (xArg->isNumber() && yArg->isNumber())
            pos = QPointF(xArg->asDouble(), yArg->asDouble());
    }

    if (pos.isNull && (len >= 2 || (!parentItem && len >= 1))) {
        // point pos
        QV4::ScopedValue posArg(scope, (*args)[parentItem ? 1 : 0]);
        const QVariant var = v4->toVariant(posArg, -1);
        if (var.userType() == QMetaType::QPointF)
            pos = var.toPointF();
    }

    if (parentItem)
        setParentItem(parentItem);

    if (pos.isNull)
        popup(menuItem);
    else
        popup(pos, menuItem);
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlmethod void QtQuick.Controls::Menu::dismiss()

    Closes all menus in the hierarchy that this menu belongs to.

    \note Unlike \l {Popup::}{close()} that only closes a menu and its sub-menus,
    \c dismiss() closes the whole hierarchy of menus, including the parent menus.
    In practice, \c close() is suitable e.g. for implementing navigation in a
    hierarchy of menus, and \c dismiss() is the appropriate method for closing
    the whole hierarchy of menus.

    \sa popup(), Popup::close()
*/
void QQuickMenu::dismiss()
{
    QQuickMenu *menu = this;
    while (menu) {
        menu->close();
        menu = QQuickMenuPrivate::get(menu)->parentMenu;
    }
}

void QQuickMenu::componentComplete()
{
    Q_D(QQuickMenu);
    QQuickPopup::componentComplete();
    d->resizeItems();
}

void QQuickMenu::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
    Q_D(QQuickMenu);
    QQuickPopup::contentItemChange(newItem, oldItem);

    if (oldItem) {
        QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children);
        QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
    }
    if (newItem) {
        QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children);
        QQuickItemPrivate::get(newItem)->updateOrAddGeometryChangeListener(d, QQuickGeometryChange::Width);
    }

    d->contentItem = newItem;
}

void QQuickMenu::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{
    Q_D(QQuickMenu);
    QQuickPopup::itemChange(change, data);

    if (change == QQuickItem::ItemVisibleHasChanged) {
        if (!data.boolValue && d->cascade) {
            // Ensure that when the menu isn't visible, there's no current item
            // the next time it's opened.
            d->setCurrentIndex(-1, Qt::OtherFocusReason);
        }
    }
}

void QQuickMenu::keyPressEvent(QKeyEvent *event)
{
    Q_D(QQuickMenu);
    QQuickPopup::keyPressEvent(event);

    // QTBUG-17051
    // Work around the fact that ListView has no way of distinguishing between
    // mouse and keyboard interaction, thanks to the "interactive" bool in Flickable.
    // What we actually want is to have a way to always allow keyboard interaction but
    // only allow flicking with the mouse when there are too many menu items to be
    // shown at once.
    switch (event->key()) {
    case Qt::Key_Up:
        if (!d->activatePreviousItem())
            d->propagateKeyEvent(event);
        break;

    case Qt::Key_Down:
        d->activateNextItem();
        break;

    case Qt::Key_Left:
    case Qt::Key_Right:
        event->ignore();
        if (d->popupItem->isMirrored() == (event->key() == Qt::Key_Right)) {
            if (d->parentMenu && d->currentItem) {
                if (!d->cascade)
                    d->parentMenu->open();
                close();
                event->accept();
            }
        } else {
            if (QQuickMenu *subMenu = d->currentSubMenu()) {
                auto subMenuPrivate = QQuickMenuPrivate::get(subMenu);
                subMenu->popup(subMenuPrivate->firstEnabledMenuItem());
                event->accept();
            }
        }
        if (!event->isAccepted())
            d->propagateKeyEvent(event);
        break;

    default:
        break;
    }
}

void QQuickMenu::timerEvent(QTimerEvent *event)
{
    Q_D(QQuickMenu);
    if (event->timerId() == d->hoverTimer) {
        if (QQuickMenu *subMenu = d->currentSubMenu())
            subMenu->open();
        d->stopHoverTimer();
        return;
    }
    QQuickPopup::timerEvent(event);
}

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

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

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

QT_END_NAMESPACE

#include "moc_qquickmenu_p.cpp"
